infra: fix minor memory leak in "api trace..."
[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 <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #if VPP_API_TEST_BUILTIN == 0
89 #include <netdb.h>
90
91 u32
92 vl (void *p)
93 {
94   return vec_len (p);
95 }
96
97 int
98 vat_socket_connect (vat_main_t * vam)
99 {
100   int rv;
101   vam->socket_client_main = &socket_client_main;
102   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
103                                       "vpp_api_test",
104                                       0 /* default socket rx, tx buffer */ )))
105     return rv;
106   /* vpp expects the client index in network order */
107   vam->my_client_index = htonl (socket_client_main.client_index);
108   return 0;
109 }
110 #else /* vpp built-in case, we don't do sockets... */
111 int
112 vat_socket_connect (vat_main_t * vam)
113 {
114   return 0;
115 }
116
117 int
118 vl_socket_client_read (int wait)
119 {
120   return -1;
121 };
122
123 int
124 vl_socket_client_write ()
125 {
126   return -1;
127 };
128
129 void *
130 vl_socket_client_msg_alloc (int nbytes)
131 {
132   return 0;
133 }
134 #endif
135
136
137 f64
138 vat_time_now (vat_main_t * vam)
139 {
140 #if VPP_API_TEST_BUILTIN
141   return vlib_time_now (vam->vlib_main);
142 #else
143   return clib_time_now (&vam->clib_time);
144 #endif
145 }
146
147 void
148 errmsg (char *fmt, ...)
149 {
150   vat_main_t *vam = &vat_main;
151   va_list va;
152   u8 *s;
153
154   va_start (va, fmt);
155   s = va_format (0, fmt, &va);
156   va_end (va);
157
158   vec_add1 (s, 0);
159
160 #if VPP_API_TEST_BUILTIN
161   vlib_cli_output (vam->vlib_main, (char *) s);
162 #else
163   {
164     if (vam->ifp != stdin)
165       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
166                vam->input_line_number);
167     fformat (vam->ofp, (char *) s);
168     fflush (vam->ofp);
169   }
170 #endif
171
172   vec_free (s);
173 }
174
175 #if VPP_API_TEST_BUILTIN == 0
176 static uword
177 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
178 {
179   vat_main_t *vam = va_arg (*args, vat_main_t *);
180   u32 *result = va_arg (*args, u32 *);
181   u8 *if_name;
182   uword *p;
183
184   if (!unformat (input, "%s", &if_name))
185     return 0;
186
187   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
188   if (p == 0)
189     return 0;
190   *result = p[0];
191   return 1;
192 }
193
194 static uword
195 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
196 {
197   return 0;
198 }
199
200 /* Parse an IP4 address %d.%d.%d.%d. */
201 uword
202 unformat_ip4_address (unformat_input_t * input, va_list * args)
203 {
204   u8 *result = va_arg (*args, u8 *);
205   unsigned a[4];
206
207   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
208     return 0;
209
210   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
211     return 0;
212
213   result[0] = a[0];
214   result[1] = a[1];
215   result[2] = a[2];
216   result[3] = a[3];
217
218   return 1;
219 }
220
221 uword
222 unformat_ethernet_address (unformat_input_t * input, va_list * args)
223 {
224   u8 *result = va_arg (*args, u8 *);
225   u32 i, a[6];
226
227   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
228                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
229     return 0;
230
231   /* Check range. */
232   for (i = 0; i < 6; i++)
233     if (a[i] >= (1 << 8))
234       return 0;
235
236   for (i = 0; i < 6; i++)
237     result[i] = a[i];
238
239   return 1;
240 }
241
242 /* Returns ethernet type as an int in host byte order. */
243 uword
244 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
245                                         va_list * args)
246 {
247   u16 *result = va_arg (*args, u16 *);
248   int type;
249
250   /* Numeric type. */
251   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
252     {
253       if (type >= (1 << 16))
254         return 0;
255       *result = type;
256       return 1;
257     }
258   return 0;
259 }
260
261 /* Parse an IP6 address. */
262 uword
263 unformat_ip6_address (unformat_input_t * input, va_list * args)
264 {
265   ip6_address_t *result = va_arg (*args, ip6_address_t *);
266   u16 hex_quads[8];
267   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
268   uword c, n_colon, double_colon_index;
269
270   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
271   double_colon_index = ARRAY_LEN (hex_quads);
272   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
273     {
274       hex_digit = 16;
275       if (c >= '0' && c <= '9')
276         hex_digit = c - '0';
277       else if (c >= 'a' && c <= 'f')
278         hex_digit = c + 10 - 'a';
279       else if (c >= 'A' && c <= 'F')
280         hex_digit = c + 10 - 'A';
281       else if (c == ':' && n_colon < 2)
282         n_colon++;
283       else
284         {
285           unformat_put_input (input);
286           break;
287         }
288
289       /* Too many hex quads. */
290       if (n_hex_quads >= ARRAY_LEN (hex_quads))
291         return 0;
292
293       if (hex_digit < 16)
294         {
295           hex_quad = (hex_quad << 4) | hex_digit;
296
297           /* Hex quad must fit in 16 bits. */
298           if (n_hex_digits >= 4)
299             return 0;
300
301           n_colon = 0;
302           n_hex_digits++;
303         }
304
305       /* Save position of :: */
306       if (n_colon == 2)
307         {
308           /* More than one :: ? */
309           if (double_colon_index < ARRAY_LEN (hex_quads))
310             return 0;
311           double_colon_index = n_hex_quads;
312         }
313
314       if (n_colon > 0 && n_hex_digits > 0)
315         {
316           hex_quads[n_hex_quads++] = hex_quad;
317           hex_quad = 0;
318           n_hex_digits = 0;
319         }
320     }
321
322   if (n_hex_digits > 0)
323     hex_quads[n_hex_quads++] = hex_quad;
324
325   {
326     word i;
327
328     /* Expand :: to appropriate number of zero hex quads. */
329     if (double_colon_index < ARRAY_LEN (hex_quads))
330       {
331         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
332
333         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
334           hex_quads[n_zero + i] = hex_quads[i];
335
336         for (i = 0; i < n_zero; i++)
337           hex_quads[double_colon_index + i] = 0;
338
339         n_hex_quads = ARRAY_LEN (hex_quads);
340       }
341
342     /* Too few hex quads given. */
343     if (n_hex_quads < ARRAY_LEN (hex_quads))
344       return 0;
345
346     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
347       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
348
349     return 1;
350   }
351 }
352
353 uword
354 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
355 {
356   u32 *r = va_arg (*args, u32 *);
357
358   if (0);
359 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
360   foreach_ipsec_policy_action
361 #undef _
362     else
363     return 0;
364   return 1;
365 }
366
367 u8 *
368 format_ipsec_crypto_alg (u8 * s, va_list * args)
369 {
370   u32 i = va_arg (*args, u32);
371   u8 *t = 0;
372
373   switch (i)
374     {
375 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
376       foreach_ipsec_crypto_alg
377 #undef _
378     default:
379       return format (s, "unknown");
380     }
381   return format (s, "%s", t);
382 }
383
384 u8 *
385 format_ipsec_integ_alg (u8 * s, va_list * args)
386 {
387   u32 i = va_arg (*args, u32);
388   u8 *t = 0;
389
390   switch (i)
391     {
392 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
393       foreach_ipsec_integ_alg
394 #undef _
395     default:
396       return format (s, "unknown");
397     }
398   return format (s, "%s", t);
399 }
400
401 #else /* VPP_API_TEST_BUILTIN == 1 */
402 static uword
403 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
404 {
405   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
406   vnet_main_t *vnm = vnet_get_main ();
407   u32 *result = va_arg (*args, u32 *);
408
409   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
410 }
411
412 static uword
413 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
414 {
415   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
416   vnet_main_t *vnm = vnet_get_main ();
417   u32 *result = va_arg (*args, u32 *);
418
419   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
420 }
421
422 #endif /* VPP_API_TEST_BUILTIN */
423
424 uword
425 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
426 {
427   u32 *r = va_arg (*args, u32 *);
428
429   if (0);
430 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
431   foreach_ipsec_crypto_alg
432 #undef _
433     else
434     return 0;
435   return 1;
436 }
437
438 uword
439 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
440 {
441   u32 *r = va_arg (*args, u32 *);
442
443   if (0);
444 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
445   foreach_ipsec_integ_alg
446 #undef _
447     else
448     return 0;
449   return 1;
450 }
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 #if (VPP_API_TEST_BUILTIN==0)
570
571 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
572 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
573 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
574 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
575
576 uword
577 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
578 {
579   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
580   mfib_itf_attribute_t attr;
581
582   old = *iflags;
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_long_names[attr]))
586       *iflags |= (1 << attr);
587   }
588   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_itf_flag_names[attr]))
591       *iflags |= (1 << attr);
592   }
593
594   return (old == *iflags ? 0 : 1);
595 }
596
597 uword
598 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
599 {
600   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
601   mfib_entry_attribute_t attr;
602
603   old = *eflags;
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_long_names[attr]))
607       *eflags |= (1 << attr);
608   }
609   FOR_EACH_MFIB_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_flag_names[attr]))
612       *eflags |= (1 << attr);
613   }
614
615   return (old == *eflags ? 0 : 1);
616 }
617
618 u8 *
619 format_ip4_address (u8 * s, va_list * args)
620 {
621   u8 *a = va_arg (*args, u8 *);
622   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
623 }
624
625 u8 *
626 format_ip6_address (u8 * s, va_list * args)
627 {
628   ip6_address_t *a = va_arg (*args, ip6_address_t *);
629   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
630
631   i_max_n_zero = ARRAY_LEN (a->as_u16);
632   max_n_zeros = 0;
633   i_first_zero = i_max_n_zero;
634   n_zeros = 0;
635   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
636     {
637       u32 is_zero = a->as_u16[i] == 0;
638       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
639         {
640           i_first_zero = i;
641           n_zeros = 0;
642         }
643       n_zeros += is_zero;
644       if ((!is_zero && n_zeros > max_n_zeros)
645           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
646         {
647           i_max_n_zero = i_first_zero;
648           max_n_zeros = n_zeros;
649           i_first_zero = ARRAY_LEN (a->as_u16);
650           n_zeros = 0;
651         }
652     }
653
654   last_double_colon = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       if (i == i_max_n_zero && max_n_zeros > 1)
658         {
659           s = format (s, "::");
660           i += max_n_zeros - 1;
661           last_double_colon = 1;
662         }
663       else
664         {
665           s = format (s, "%s%x",
666                       (last_double_colon || i == 0) ? "" : ":",
667                       clib_net_to_host_u16 (a->as_u16[i]));
668           last_double_colon = 0;
669         }
670     }
671
672   return s;
673 }
674
675 /* Format an IP46 address. */
676 u8 *
677 format_ip46_address (u8 * s, va_list * args)
678 {
679   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
680   ip46_type_t type = va_arg (*args, ip46_type_t);
681   int is_ip4 = 1;
682
683   switch (type)
684     {
685     case IP46_TYPE_ANY:
686       is_ip4 = ip46_address_is_ip4 (ip46);
687       break;
688     case IP46_TYPE_IP4:
689       is_ip4 = 1;
690       break;
691     case IP46_TYPE_IP6:
692       is_ip4 = 0;
693       break;
694     }
695
696   return is_ip4 ?
697     format (s, "%U", format_ip4_address, &ip46->ip4) :
698     format (s, "%U", format_ip6_address, &ip46->ip6);
699 }
700
701 u8 *
702 format_ethernet_address (u8 * s, va_list * args)
703 {
704   u8 *a = va_arg (*args, u8 *);
705
706   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
707                  a[0], a[1], a[2], a[3], a[4], a[5]);
708 }
709 #endif
710
711 static void
712 increment_v4_address (ip4_address_t * a)
713 {
714   u32 v;
715
716   v = ntohl (a->as_u32) + 1;
717   a->as_u32 = ntohl (v);
718 }
719
720 static void
721 increment_vl_v4_address (vl_api_ip4_address_t * a)
722 {
723   u32 v;
724
725   v = *(u32 *) a;
726   v = ntohl (v);
727   v++;
728   v = ntohl (v);
729   clib_memcpy (a, &v, sizeof (v));
730 }
731
732 static void
733 increment_vl_address (vl_api_address_t * a)
734 {
735   if (ADDRESS_IP4 == a->af)
736     increment_vl_v4_address (&a->un.ip4);
737 }
738
739 static void
740 increment_v6_address (ip6_address_t * a)
741 {
742   u64 v0, v1;
743
744   v0 = clib_net_to_host_u64 (a->as_u64[0]);
745   v1 = clib_net_to_host_u64 (a->as_u64[1]);
746
747   v1 += 1;
748   if (v1 == 0)
749     v0 += 1;
750   a->as_u64[0] = clib_net_to_host_u64 (v0);
751   a->as_u64[1] = clib_net_to_host_u64 (v1);
752 }
753
754 static void
755 increment_mac_address (u8 * mac)
756 {
757   u64 tmp = *((u64 *) mac);
758   tmp = clib_net_to_host_u64 (tmp);
759   tmp += 1 << 16;               /* skip unused (least significant) octets */
760   tmp = clib_host_to_net_u64 (tmp);
761
762   clib_memcpy (mac, &tmp, 6);
763 }
764
765 static void vl_api_create_loopback_reply_t_handler
766   (vl_api_create_loopback_reply_t * mp)
767 {
768   vat_main_t *vam = &vat_main;
769   i32 retval = ntohl (mp->retval);
770
771   vam->retval = retval;
772   vam->regenerate_interface_table = 1;
773   vam->sw_if_index = ntohl (mp->sw_if_index);
774   vam->result_ready = 1;
775 }
776
777 static void vl_api_create_loopback_reply_t_handler_json
778   (vl_api_create_loopback_reply_t * mp)
779 {
780   vat_main_t *vam = &vat_main;
781   vat_json_node_t node;
782
783   vat_json_init_object (&node);
784   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
785   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
786
787   vat_json_print (vam->ofp, &node);
788   vat_json_free (&node);
789   vam->retval = ntohl (mp->retval);
790   vam->result_ready = 1;
791 }
792
793 static void vl_api_create_loopback_instance_reply_t_handler
794   (vl_api_create_loopback_instance_reply_t * mp)
795 {
796   vat_main_t *vam = &vat_main;
797   i32 retval = ntohl (mp->retval);
798
799   vam->retval = retval;
800   vam->regenerate_interface_table = 1;
801   vam->sw_if_index = ntohl (mp->sw_if_index);
802   vam->result_ready = 1;
803 }
804
805 static void vl_api_create_loopback_instance_reply_t_handler_json
806   (vl_api_create_loopback_instance_reply_t * mp)
807 {
808   vat_main_t *vam = &vat_main;
809   vat_json_node_t node;
810
811   vat_json_init_object (&node);
812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
814
815   vat_json_print (vam->ofp, &node);
816   vat_json_free (&node);
817   vam->retval = ntohl (mp->retval);
818   vam->result_ready = 1;
819 }
820
821 static void vl_api_af_packet_create_reply_t_handler
822   (vl_api_af_packet_create_reply_t * mp)
823 {
824   vat_main_t *vam = &vat_main;
825   i32 retval = ntohl (mp->retval);
826
827   vam->retval = retval;
828   vam->regenerate_interface_table = 1;
829   vam->sw_if_index = ntohl (mp->sw_if_index);
830   vam->result_ready = 1;
831 }
832
833 static void vl_api_af_packet_create_reply_t_handler_json
834   (vl_api_af_packet_create_reply_t * mp)
835 {
836   vat_main_t *vam = &vat_main;
837   vat_json_node_t node;
838
839   vat_json_init_object (&node);
840   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
841   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
842
843   vat_json_print (vam->ofp, &node);
844   vat_json_free (&node);
845
846   vam->retval = ntohl (mp->retval);
847   vam->result_ready = 1;
848 }
849
850 static void vl_api_create_vlan_subif_reply_t_handler
851   (vl_api_create_vlan_subif_reply_t * mp)
852 {
853   vat_main_t *vam = &vat_main;
854   i32 retval = ntohl (mp->retval);
855
856   vam->retval = retval;
857   vam->regenerate_interface_table = 1;
858   vam->sw_if_index = ntohl (mp->sw_if_index);
859   vam->result_ready = 1;
860 }
861
862 static void vl_api_create_vlan_subif_reply_t_handler_json
863   (vl_api_create_vlan_subif_reply_t * mp)
864 {
865   vat_main_t *vam = &vat_main;
866   vat_json_node_t node;
867
868   vat_json_init_object (&node);
869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
870   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
871
872   vat_json_print (vam->ofp, &node);
873   vat_json_free (&node);
874
875   vam->retval = ntohl (mp->retval);
876   vam->result_ready = 1;
877 }
878
879 static void vl_api_create_subif_reply_t_handler
880   (vl_api_create_subif_reply_t * mp)
881 {
882   vat_main_t *vam = &vat_main;
883   i32 retval = ntohl (mp->retval);
884
885   vam->retval = retval;
886   vam->regenerate_interface_table = 1;
887   vam->sw_if_index = ntohl (mp->sw_if_index);
888   vam->result_ready = 1;
889 }
890
891 static void vl_api_create_subif_reply_t_handler_json
892   (vl_api_create_subif_reply_t * mp)
893 {
894   vat_main_t *vam = &vat_main;
895   vat_json_node_t node;
896
897   vat_json_init_object (&node);
898   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
899   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
900
901   vat_json_print (vam->ofp, &node);
902   vat_json_free (&node);
903
904   vam->retval = ntohl (mp->retval);
905   vam->result_ready = 1;
906 }
907
908 static void vl_api_interface_name_renumber_reply_t_handler
909   (vl_api_interface_name_renumber_reply_t * mp)
910 {
911   vat_main_t *vam = &vat_main;
912   i32 retval = ntohl (mp->retval);
913
914   vam->retval = retval;
915   vam->regenerate_interface_table = 1;
916   vam->result_ready = 1;
917 }
918
919 static void vl_api_interface_name_renumber_reply_t_handler_json
920   (vl_api_interface_name_renumber_reply_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   vat_json_node_t node;
924
925   vat_json_init_object (&node);
926   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
927
928   vat_json_print (vam->ofp, &node);
929   vat_json_free (&node);
930
931   vam->retval = ntohl (mp->retval);
932   vam->result_ready = 1;
933 }
934
935 /*
936  * Special-case: build the interface table, maintain
937  * the next loopback sw_if_index vbl.
938  */
939 static void vl_api_sw_interface_details_t_handler
940   (vl_api_sw_interface_details_t * mp)
941 {
942   vat_main_t *vam = &vat_main;
943   u8 *s = format (0, "%s%c", mp->interface_name, 0);
944
945   hash_set_mem (vam->sw_if_index_by_interface_name, s,
946                 ntohl (mp->sw_if_index));
947
948   /* In sub interface case, fill the sub interface table entry */
949   if (mp->sw_if_index != mp->sup_sw_if_index)
950     {
951       sw_interface_subif_t *sub = NULL;
952
953       vec_add2 (vam->sw_if_subif_table, sub, 1);
954
955       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
956       strncpy ((char *) sub->interface_name, (char *) s,
957                vec_len (sub->interface_name));
958       sub->sw_if_index = ntohl (mp->sw_if_index);
959       sub->sub_id = ntohl (mp->sub_id);
960
961       sub->sub_dot1ad = mp->sub_dot1ad;
962       sub->sub_number_of_tags = mp->sub_number_of_tags;
963       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
964       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
965       sub->sub_exact_match = mp->sub_exact_match;
966       sub->sub_default = mp->sub_default;
967       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
968       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
969
970       /* vlan tag rewrite */
971       sub->vtr_op = ntohl (mp->vtr_op);
972       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
973       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
974       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
975     }
976 }
977
978 static void vl_api_sw_interface_details_t_handler_json
979   (vl_api_sw_interface_details_t * mp)
980 {
981   vat_main_t *vam = &vat_main;
982   vat_json_node_t *node = NULL;
983
984   if (VAT_JSON_ARRAY != vam->json_tree.type)
985     {
986       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
987       vat_json_init_array (&vam->json_tree);
988     }
989   node = vat_json_array_add (&vam->json_tree);
990
991   vat_json_init_object (node);
992   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
993   vat_json_object_add_uint (node, "sup_sw_if_index",
994                             ntohl (mp->sup_sw_if_index));
995   vat_json_object_add_uint (node, "l2_address_length",
996                             ntohl (mp->l2_address_length));
997   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
998                              sizeof (mp->l2_address));
999   vat_json_object_add_string_copy (node, "interface_name",
1000                                    mp->interface_name);
1001   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1002   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1003   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1004   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1005   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1006   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1007   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1008   vat_json_object_add_uint (node, "sub_number_of_tags",
1009                             mp->sub_number_of_tags);
1010   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1011                             ntohs (mp->sub_outer_vlan_id));
1012   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1013                             ntohs (mp->sub_inner_vlan_id));
1014   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1015   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1016   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1017                             mp->sub_outer_vlan_id_any);
1018   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1019                             mp->sub_inner_vlan_id_any);
1020   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1021   vat_json_object_add_uint (node, "vtr_push_dot1q",
1022                             ntohl (mp->vtr_push_dot1q));
1023   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1024   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1025   if (mp->sub_dot1ah)
1026     {
1027       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1028                                        format (0, "%U",
1029                                                format_ethernet_address,
1030                                                &mp->b_dmac));
1031       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1032                                        format (0, "%U",
1033                                                format_ethernet_address,
1034                                                &mp->b_smac));
1035       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1036       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1037     }
1038 }
1039
1040 #if VPP_API_TEST_BUILTIN == 0
1041 static void vl_api_sw_interface_event_t_handler
1042   (vl_api_sw_interface_event_t * mp)
1043 {
1044   vat_main_t *vam = &vat_main;
1045   if (vam->interface_event_display)
1046     errmsg ("interface flags: sw_if_index %d %s %s",
1047             ntohl (mp->sw_if_index),
1048             mp->admin_up_down ? "admin-up" : "admin-down",
1049             mp->link_up_down ? "link-up" : "link-down");
1050 }
1051 #endif
1052
1053 __clib_unused static void
1054 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1055 {
1056   /* JSON output not supported */
1057 }
1058
1059 static void
1060 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1061 {
1062   vat_main_t *vam = &vat_main;
1063   i32 retval = ntohl (mp->retval);
1064
1065   vam->retval = retval;
1066   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1067   vam->result_ready = 1;
1068 }
1069
1070 static void
1071 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1072 {
1073   vat_main_t *vam = &vat_main;
1074   vat_json_node_t node;
1075   api_main_t *am = &api_main;
1076   void *oldheap;
1077   u8 *reply;
1078
1079   vat_json_init_object (&node);
1080   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1081   vat_json_object_add_uint (&node, "reply_in_shmem",
1082                             ntohl (mp->reply_in_shmem));
1083   /* Toss the shared-memory original... */
1084   pthread_mutex_lock (&am->vlib_rp->mutex);
1085   oldheap = svm_push_data_heap (am->vlib_rp);
1086
1087   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1088   vec_free (reply);
1089
1090   svm_pop_heap (oldheap);
1091   pthread_mutex_unlock (&am->vlib_rp->mutex);
1092
1093   vat_json_print (vam->ofp, &node);
1094   vat_json_free (&node);
1095
1096   vam->retval = ntohl (mp->retval);
1097   vam->result_ready = 1;
1098 }
1099
1100 static void
1101 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   i32 retval = ntohl (mp->retval);
1105   u32 length = vl_api_string_len (&mp->reply);
1106
1107   vec_reset_length (vam->cmd_reply);
1108
1109   vam->retval = retval;
1110   if (retval == 0)
1111     {
1112       vec_validate (vam->cmd_reply, length);
1113       clib_memcpy ((char *) (vam->cmd_reply),
1114                    vl_api_from_api_string (&mp->reply), length);
1115       vam->cmd_reply[length] = 0;
1116     }
1117   vam->result_ready = 1;
1118 }
1119
1120 static void
1121 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   vat_json_node_t node;
1125
1126   vec_reset_length (vam->cmd_reply);
1127
1128   vat_json_init_object (&node);
1129   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1130   vat_json_object_add_string_copy (&node, "reply",
1131                                    vl_api_from_api_string (&mp->reply));
1132
1133   vat_json_print (vam->ofp, &node);
1134   vat_json_free (&node);
1135
1136   vam->retval = ntohl (mp->retval);
1137   vam->result_ready = 1;
1138 }
1139
1140 static void vl_api_classify_add_del_table_reply_t_handler
1141   (vl_api_classify_add_del_table_reply_t * mp)
1142 {
1143   vat_main_t *vam = &vat_main;
1144   i32 retval = ntohl (mp->retval);
1145   if (vam->async_mode)
1146     {
1147       vam->async_errors += (retval < 0);
1148     }
1149   else
1150     {
1151       vam->retval = retval;
1152       if (retval == 0 &&
1153           ((mp->new_table_index != 0xFFFFFFFF) ||
1154            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1155            (mp->match_n_vectors != 0xFFFFFFFF)))
1156         /*
1157          * Note: this is just barely thread-safe, depends on
1158          * the main thread spinning waiting for an answer...
1159          */
1160         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1161                 ntohl (mp->new_table_index),
1162                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1163       vam->result_ready = 1;
1164     }
1165 }
1166
1167 static void vl_api_classify_add_del_table_reply_t_handler_json
1168   (vl_api_classify_add_del_table_reply_t * mp)
1169 {
1170   vat_main_t *vam = &vat_main;
1171   vat_json_node_t node;
1172
1173   vat_json_init_object (&node);
1174   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1175   vat_json_object_add_uint (&node, "new_table_index",
1176                             ntohl (mp->new_table_index));
1177   vat_json_object_add_uint (&node, "skip_n_vectors",
1178                             ntohl (mp->skip_n_vectors));
1179   vat_json_object_add_uint (&node, "match_n_vectors",
1180                             ntohl (mp->match_n_vectors));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_node_index_reply_t_handler
1190   (vl_api_get_node_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("node index %d", ntohl (mp->node_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_node_index_reply_t_handler_json
1208   (vl_api_get_node_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_get_next_index_reply_t_handler
1225   (vl_api_get_next_index_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next node index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_get_next_index_reply_t_handler_json
1243   (vl_api_get_next_index_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_add_node_next_reply_t_handler
1260   (vl_api_add_node_next_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264   if (vam->async_mode)
1265     {
1266       vam->async_errors += (retval < 0);
1267     }
1268   else
1269     {
1270       vam->retval = retval;
1271       if (retval == 0)
1272         errmsg ("next index %d", ntohl (mp->next_index));
1273       vam->result_ready = 1;
1274     }
1275 }
1276
1277 static void vl_api_add_node_next_reply_t_handler_json
1278   (vl_api_add_node_next_reply_t * mp)
1279 {
1280   vat_main_t *vam = &vat_main;
1281   vat_json_node_t node;
1282
1283   vat_json_init_object (&node);
1284   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1285   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void vl_api_show_version_reply_t_handler
1295   (vl_api_show_version_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (retval >= 0)
1301     {
1302       char *s;
1303       char *p = (char *) &mp->program;
1304
1305       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1306       errmsg ("        program: %s\n", s);
1307       free (s);
1308
1309       p +=
1310         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1311       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1312       errmsg ("        version: %s\n", s);
1313       free (s);
1314
1315       p +=
1316         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1317       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1318       errmsg ("     build date: %s\n", s);
1319       free (s);
1320
1321       p +=
1322         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1323       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1324       errmsg ("build directory: %s\n", s);
1325       free (s);
1326     }
1327   vam->retval = retval;
1328   vam->result_ready = 1;
1329 }
1330
1331 static void vl_api_show_version_reply_t_handler_json
1332   (vl_api_show_version_reply_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t node;
1336
1337   vat_json_init_object (&node);
1338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339   char *p = (char *) &mp->program;
1340   vat_json_object_add_string_copy (&node, "program",
1341                                    vl_api_from_api_string ((vl_api_string_t *)
1342                                                            p));
1343   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1344   vat_json_object_add_string_copy (&node, "version",
1345                                    vl_api_from_api_string ((vl_api_string_t *)
1346                                                            p));
1347   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1348   vat_json_object_add_string_copy (&node, "build_date",
1349                                    vl_api_from_api_string ((vl_api_string_t *)
1350                                                            p));
1351   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1352   vat_json_object_add_string_copy (&node, "build_directory",
1353                                    vl_api_from_api_string ((vl_api_string_t *)
1354                                                            p));
1355
1356   vat_json_print (vam->ofp, &node);
1357   vat_json_free (&node);
1358
1359   vam->retval = ntohl (mp->retval);
1360   vam->result_ready = 1;
1361 }
1362
1363 static void vl_api_show_threads_reply_t_handler
1364   (vl_api_show_threads_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   i32 retval = ntohl (mp->retval);
1368   int i, count = 0;
1369
1370   if (retval >= 0)
1371     count = ntohl (mp->count);
1372
1373   for (i = 0; i < count; i++)
1374     print (vam->ofp,
1375            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1376            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1377            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1378            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1379            ntohl (mp->thread_data[i].cpu_socket));
1380
1381   vam->retval = retval;
1382   vam->result_ready = 1;
1383 }
1384
1385 static void vl_api_show_threads_reply_t_handler_json
1386   (vl_api_show_threads_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   vat_json_node_t node;
1390   vl_api_thread_data_t *td;
1391   i32 retval = ntohl (mp->retval);
1392   int i, count = 0;
1393
1394   if (retval >= 0)
1395     count = ntohl (mp->count);
1396
1397   vat_json_init_object (&node);
1398   vat_json_object_add_int (&node, "retval", retval);
1399   vat_json_object_add_uint (&node, "count", count);
1400
1401   for (i = 0; i < count; i++)
1402     {
1403       td = &mp->thread_data[i];
1404       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1405       vat_json_object_add_string_copy (&node, "name", td->name);
1406       vat_json_object_add_string_copy (&node, "type", td->type);
1407       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1408       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1409       vat_json_object_add_int (&node, "core", ntohl (td->id));
1410       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1411     }
1412
1413   vat_json_print (vam->ofp, &node);
1414   vat_json_free (&node);
1415
1416   vam->retval = retval;
1417   vam->result_ready = 1;
1418 }
1419
1420 static int
1421 api_show_threads (vat_main_t * vam)
1422 {
1423   vl_api_show_threads_t *mp;
1424   int ret;
1425
1426   print (vam->ofp,
1427          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1428          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1429
1430   M (SHOW_THREADS, mp);
1431
1432   S (mp);
1433   W (ret);
1434   return ret;
1435 }
1436
1437 static void
1438 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1439 {
1440   u32 sw_if_index = ntohl (mp->sw_if_index);
1441   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1442           mp->mac_ip ? "mac/ip binding" : "address resolution",
1443           ntohl (mp->pid), format_ip4_address, mp->ip,
1444           format_vl_api_mac_address, &mp->mac, sw_if_index);
1445 }
1446
1447 static void
1448 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1449 {
1450   /* JSON output not supported */
1451 }
1452
1453 static void
1454 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1455 {
1456   u32 sw_if_index = ntohl (mp->sw_if_index);
1457   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1458           mp->mac_ip ? "mac/ip binding" : "address resolution",
1459           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1460           format_vl_api_mac_address, mp->mac, sw_if_index);
1461 }
1462
1463 static void
1464 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1465 {
1466   /* JSON output not supported */
1467 }
1468
1469 static void
1470 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1471 {
1472   u32 n_macs = ntohl (mp->n_macs);
1473   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1474           ntohl (mp->pid), mp->client_index, n_macs);
1475   int i;
1476   for (i = 0; i < n_macs; i++)
1477     {
1478       vl_api_mac_entry_t *mac = &mp->mac[i];
1479       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1480               i + 1, ntohl (mac->sw_if_index),
1481               format_ethernet_address, mac->mac_addr, mac->action);
1482       if (i == 1000)
1483         break;
1484     }
1485 }
1486
1487 static void
1488 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1489 {
1490   /* JSON output not supported */
1491 }
1492
1493 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1494 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1495
1496 /*
1497  * Special-case: build the bridge domain table, maintain
1498  * the next bd id vbl.
1499  */
1500 static void vl_api_bridge_domain_details_t_handler
1501   (vl_api_bridge_domain_details_t * mp)
1502 {
1503   vat_main_t *vam = &vat_main;
1504   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1505   int i;
1506
1507   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1508          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1509
1510   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1511          ntohl (mp->bd_id), mp->learn, mp->forward,
1512          mp->flood, ntohl (mp->bvi_sw_if_index),
1513          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1514
1515   if (n_sw_ifs)
1516     {
1517       vl_api_bridge_domain_sw_if_t *sw_ifs;
1518       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1519              "Interface Name");
1520
1521       sw_ifs = mp->sw_if_details;
1522       for (i = 0; i < n_sw_ifs; i++)
1523         {
1524           u8 *sw_if_name = 0;
1525           u32 sw_if_index;
1526           hash_pair_t *p;
1527
1528           sw_if_index = ntohl (sw_ifs->sw_if_index);
1529
1530           /* *INDENT-OFF* */
1531           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1532                              ({
1533                                if ((u32) p->value[0] == sw_if_index)
1534                                  {
1535                                    sw_if_name = (u8 *)(p->key);
1536                                    break;
1537                                  }
1538                              }));
1539           /* *INDENT-ON* */
1540           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1541                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1542                  "sw_if_index not found!");
1543
1544           sw_ifs++;
1545         }
1546     }
1547 }
1548
1549 static void vl_api_bridge_domain_details_t_handler_json
1550   (vl_api_bridge_domain_details_t * mp)
1551 {
1552   vat_main_t *vam = &vat_main;
1553   vat_json_node_t *node, *array = NULL;
1554   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1555
1556   if (VAT_JSON_ARRAY != vam->json_tree.type)
1557     {
1558       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1559       vat_json_init_array (&vam->json_tree);
1560     }
1561   node = vat_json_array_add (&vam->json_tree);
1562
1563   vat_json_init_object (node);
1564   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1565   vat_json_object_add_uint (node, "flood", mp->flood);
1566   vat_json_object_add_uint (node, "forward", mp->forward);
1567   vat_json_object_add_uint (node, "learn", mp->learn);
1568   vat_json_object_add_uint (node, "bvi_sw_if_index",
1569                             ntohl (mp->bvi_sw_if_index));
1570   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1571   array = vat_json_object_add (node, "sw_if");
1572   vat_json_init_array (array);
1573
1574
1575
1576   if (n_sw_ifs)
1577     {
1578       vl_api_bridge_domain_sw_if_t *sw_ifs;
1579       int i;
1580
1581       sw_ifs = mp->sw_if_details;
1582       for (i = 0; i < n_sw_ifs; i++)
1583         {
1584           node = vat_json_array_add (array);
1585           vat_json_init_object (node);
1586           vat_json_object_add_uint (node, "sw_if_index",
1587                                     ntohl (sw_ifs->sw_if_index));
1588           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1589           sw_ifs++;
1590         }
1591     }
1592 }
1593
1594 static void vl_api_control_ping_reply_t_handler
1595   (vl_api_control_ping_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->result_ready = 1;
1607     }
1608   if (vam->socket_client_main)
1609     vam->socket_client_main->control_pings_outstanding--;
1610 }
1611
1612 static void vl_api_control_ping_reply_t_handler_json
1613   (vl_api_control_ping_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   i32 retval = ntohl (mp->retval);
1617
1618   if (VAT_JSON_NONE != vam->json_tree.type)
1619     {
1620       vat_json_print (vam->ofp, &vam->json_tree);
1621       vat_json_free (&vam->json_tree);
1622       vam->json_tree.type = VAT_JSON_NONE;
1623     }
1624   else
1625     {
1626       /* just print [] */
1627       vat_json_init_array (&vam->json_tree);
1628       vat_json_print (vam->ofp, &vam->json_tree);
1629       vam->json_tree.type = VAT_JSON_NONE;
1630     }
1631
1632   vam->retval = retval;
1633   vam->result_ready = 1;
1634 }
1635
1636 static void
1637   vl_api_bridge_domain_set_mac_age_reply_t_handler
1638   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->result_ready = 1;
1650     }
1651 }
1652
1653 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1654   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   vat_json_node_t node;
1658
1659   vat_json_init_object (&node);
1660   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1661
1662   vat_json_print (vam->ofp, &node);
1663   vat_json_free (&node);
1664
1665   vam->retval = ntohl (mp->retval);
1666   vam->result_ready = 1;
1667 }
1668
1669 static void
1670 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_l2_flags_reply_t_handler_json
1686   (vl_api_l2_flags_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1694                             ntohl (mp->resulting_feature_bitmap));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void vl_api_bridge_flags_reply_t_handler
1704   (vl_api_bridge_flags_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_bridge_flags_reply_t_handler_json
1720   (vl_api_bridge_flags_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1728                             ntohl (mp->resulting_feature_bitmap));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737 static void
1738 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   i32 retval = ntohl (mp->retval);
1742   if (vam->async_mode)
1743     {
1744       vam->async_errors += (retval < 0);
1745     }
1746   else
1747     {
1748       vam->retval = retval;
1749       vam->sw_if_index = ntohl (mp->sw_if_index);
1750       vam->result_ready = 1;
1751     }
1752
1753 }
1754
1755 static void vl_api_tap_create_v2_reply_t_handler_json
1756   (vl_api_tap_create_v2_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   vat_json_node_t node;
1760
1761   vat_json_init_object (&node);
1762   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1763   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1764
1765   vat_json_print (vam->ofp, &node);
1766   vat_json_free (&node);
1767
1768   vam->retval = ntohl (mp->retval);
1769   vam->result_ready = 1;
1770
1771 }
1772
1773 static void
1774 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777   i32 retval = ntohl (mp->retval);
1778   if (vam->async_mode)
1779     {
1780       vam->async_errors += (retval < 0);
1781     }
1782   else
1783     {
1784       vam->retval = retval;
1785       vam->result_ready = 1;
1786     }
1787 }
1788
1789 static void vl_api_tap_delete_v2_reply_t_handler_json
1790   (vl_api_tap_delete_v2_reply_t * mp)
1791 {
1792   vat_main_t *vam = &vat_main;
1793   vat_json_node_t node;
1794
1795   vat_json_init_object (&node);
1796   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1797
1798   vat_json_print (vam->ofp, &node);
1799   vat_json_free (&node);
1800
1801   vam->retval = ntohl (mp->retval);
1802   vam->result_ready = 1;
1803 }
1804
1805 static void
1806 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1807                                           mp)
1808 {
1809   vat_main_t *vam = &vat_main;
1810   i32 retval = ntohl (mp->retval);
1811   if (vam->async_mode)
1812     {
1813       vam->async_errors += (retval < 0);
1814     }
1815   else
1816     {
1817       vam->retval = retval;
1818       vam->sw_if_index = ntohl (mp->sw_if_index);
1819       vam->result_ready = 1;
1820     }
1821 }
1822
1823 static void vl_api_virtio_pci_create_reply_t_handler_json
1824   (vl_api_virtio_pci_create_reply_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827   vat_json_node_t node;
1828
1829   vat_json_init_object (&node);
1830   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1831   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1832
1833   vat_json_print (vam->ofp, &node);
1834   vat_json_free (&node);
1835
1836   vam->retval = ntohl (mp->retval);
1837   vam->result_ready = 1;
1838
1839 }
1840
1841 static void
1842 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1843                                           mp)
1844 {
1845   vat_main_t *vam = &vat_main;
1846   i32 retval = ntohl (mp->retval);
1847   if (vam->async_mode)
1848     {
1849       vam->async_errors += (retval < 0);
1850     }
1851   else
1852     {
1853       vam->retval = retval;
1854       vam->result_ready = 1;
1855     }
1856 }
1857
1858 static void vl_api_virtio_pci_delete_reply_t_handler_json
1859   (vl_api_virtio_pci_delete_reply_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   vat_json_node_t node;
1863
1864   vat_json_init_object (&node);
1865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1866
1867   vat_json_print (vam->ofp, &node);
1868   vat_json_free (&node);
1869
1870   vam->retval = ntohl (mp->retval);
1871   vam->result_ready = 1;
1872 }
1873
1874 static void
1875 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   i32 retval = ntohl (mp->retval);
1879
1880   if (vam->async_mode)
1881     {
1882       vam->async_errors += (retval < 0);
1883     }
1884   else
1885     {
1886       vam->retval = retval;
1887       vam->sw_if_index = ntohl (mp->sw_if_index);
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_bond_create_reply_t_handler_json
1893   (vl_api_bond_create_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1901
1902   vat_json_print (vam->ofp, &node);
1903   vat_json_free (&node);
1904
1905   vam->retval = ntohl (mp->retval);
1906   vam->result_ready = 1;
1907 }
1908
1909 static void
1910 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1911 {
1912   vat_main_t *vam = &vat_main;
1913   i32 retval = ntohl (mp->retval);
1914
1915   if (vam->async_mode)
1916     {
1917       vam->async_errors += (retval < 0);
1918     }
1919   else
1920     {
1921       vam->retval = retval;
1922       vam->result_ready = 1;
1923     }
1924 }
1925
1926 static void vl_api_bond_delete_reply_t_handler_json
1927   (vl_api_bond_delete_reply_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t node;
1931
1932   vat_json_init_object (&node);
1933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1934
1935   vat_json_print (vam->ofp, &node);
1936   vat_json_free (&node);
1937
1938   vam->retval = ntohl (mp->retval);
1939   vam->result_ready = 1;
1940 }
1941
1942 static void
1943 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   i32 retval = ntohl (mp->retval);
1947
1948   if (vam->async_mode)
1949     {
1950       vam->async_errors += (retval < 0);
1951     }
1952   else
1953     {
1954       vam->retval = retval;
1955       vam->result_ready = 1;
1956     }
1957 }
1958
1959 static void vl_api_bond_enslave_reply_t_handler_json
1960   (vl_api_bond_enslave_reply_t * mp)
1961 {
1962   vat_main_t *vam = &vat_main;
1963   vat_json_node_t node;
1964
1965   vat_json_init_object (&node);
1966   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1967
1968   vat_json_print (vam->ofp, &node);
1969   vat_json_free (&node);
1970
1971   vam->retval = ntohl (mp->retval);
1972   vam->result_ready = 1;
1973 }
1974
1975 static void
1976 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1977                                           mp)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   i32 retval = ntohl (mp->retval);
1981
1982   if (vam->async_mode)
1983     {
1984       vam->async_errors += (retval < 0);
1985     }
1986   else
1987     {
1988       vam->retval = retval;
1989       vam->result_ready = 1;
1990     }
1991 }
1992
1993 static void vl_api_bond_detach_slave_reply_t_handler_json
1994   (vl_api_bond_detach_slave_reply_t * mp)
1995 {
1996   vat_main_t *vam = &vat_main;
1997   vat_json_node_t node;
1998
1999   vat_json_init_object (&node);
2000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2001
2002   vat_json_print (vam->ofp, &node);
2003   vat_json_free (&node);
2004
2005   vam->retval = ntohl (mp->retval);
2006   vam->result_ready = 1;
2007 }
2008
2009 static void vl_api_sw_interface_bond_details_t_handler
2010   (vl_api_sw_interface_bond_details_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013
2014   print (vam->ofp,
2015          "%-16s %-12d %-12U %-13U %-14u %-14u",
2016          mp->interface_name, ntohl (mp->sw_if_index),
2017          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2018          ntohl (mp->active_slaves), ntohl (mp->slaves));
2019 }
2020
2021 static void vl_api_sw_interface_bond_details_t_handler_json
2022   (vl_api_sw_interface_bond_details_t * mp)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   vat_json_node_t *node = NULL;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032   node = vat_json_array_add (&vam->json_tree);
2033
2034   vat_json_init_object (node);
2035   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2036   vat_json_object_add_string_copy (node, "interface_name",
2037                                    mp->interface_name);
2038   vat_json_object_add_uint (node, "mode", mp->mode);
2039   vat_json_object_add_uint (node, "load_balance", mp->lb);
2040   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2041   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2042 }
2043
2044 static int
2045 api_sw_interface_bond_dump (vat_main_t * vam)
2046 {
2047   vl_api_sw_interface_bond_dump_t *mp;
2048   vl_api_control_ping_t *mp_ping;
2049   int ret;
2050
2051   print (vam->ofp,
2052          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2053          "interface name", "sw_if_index", "mode", "load balance",
2054          "active slaves", "slaves");
2055
2056   /* Get list of bond interfaces */
2057   M (SW_INTERFACE_BOND_DUMP, mp);
2058   S (mp);
2059
2060   /* Use a control ping for synchronization */
2061   MPING (CONTROL_PING, mp_ping);
2062   S (mp_ping);
2063
2064   W (ret);
2065   return ret;
2066 }
2067
2068 static void vl_api_sw_interface_slave_details_t_handler
2069   (vl_api_sw_interface_slave_details_t * mp)
2070 {
2071   vat_main_t *vam = &vat_main;
2072
2073   print (vam->ofp,
2074          "%-25s %-12d %-12d %d", mp->interface_name,
2075          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2076 }
2077
2078 static void vl_api_sw_interface_slave_details_t_handler_json
2079   (vl_api_sw_interface_slave_details_t * mp)
2080 {
2081   vat_main_t *vam = &vat_main;
2082   vat_json_node_t *node = NULL;
2083
2084   if (VAT_JSON_ARRAY != vam->json_tree.type)
2085     {
2086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2087       vat_json_init_array (&vam->json_tree);
2088     }
2089   node = vat_json_array_add (&vam->json_tree);
2090
2091   vat_json_init_object (node);
2092   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2093   vat_json_object_add_string_copy (node, "interface_name",
2094                                    mp->interface_name);
2095   vat_json_object_add_uint (node, "passive", mp->is_passive);
2096   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2097 }
2098
2099 static int
2100 api_sw_interface_slave_dump (vat_main_t * vam)
2101 {
2102   unformat_input_t *i = vam->input;
2103   vl_api_sw_interface_slave_dump_t *mp;
2104   vl_api_control_ping_t *mp_ping;
2105   u32 sw_if_index = ~0;
2106   u8 sw_if_index_set = 0;
2107   int ret;
2108
2109   /* Parse args required to build the message */
2110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2111     {
2112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2113         sw_if_index_set = 1;
2114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2115         sw_if_index_set = 1;
2116       else
2117         break;
2118     }
2119
2120   if (sw_if_index_set == 0)
2121     {
2122       errmsg ("missing vpp interface name. ");
2123       return -99;
2124     }
2125
2126   print (vam->ofp,
2127          "\n%-25s %-12s %-12s %s",
2128          "slave interface name", "sw_if_index", "passive", "long_timeout");
2129
2130   /* Get list of bond interfaces */
2131   M (SW_INTERFACE_SLAVE_DUMP, mp);
2132   mp->sw_if_index = ntohl (sw_if_index);
2133   S (mp);
2134
2135   /* Use a control ping for synchronization */
2136   MPING (CONTROL_PING, mp_ping);
2137   S (mp_ping);
2138
2139   W (ret);
2140   return ret;
2141 }
2142
2143 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2144   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2145 {
2146   vat_main_t *vam = &vat_main;
2147   i32 retval = ntohl (mp->retval);
2148   if (vam->async_mode)
2149     {
2150       vam->async_errors += (retval < 0);
2151     }
2152   else
2153     {
2154       vam->retval = retval;
2155       vam->sw_if_index = ntohl (mp->sw_if_index);
2156       vam->result_ready = 1;
2157     }
2158   vam->regenerate_interface_table = 1;
2159 }
2160
2161 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2162   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2163 {
2164   vat_main_t *vam = &vat_main;
2165   vat_json_node_t node;
2166
2167   vat_json_init_object (&node);
2168   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2169   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2170                             ntohl (mp->sw_if_index));
2171
2172   vat_json_print (vam->ofp, &node);
2173   vat_json_free (&node);
2174
2175   vam->retval = ntohl (mp->retval);
2176   vam->result_ready = 1;
2177 }
2178
2179 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2180   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       vam->retval = retval;
2191       vam->sw_if_index = ntohl (mp->sw_if_index);
2192       vam->result_ready = 1;
2193     }
2194 }
2195
2196 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2197   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vat_json_node_t node;
2201
2202   vat_json_init_object (&node);
2203   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2204   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2214   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   i32 retval = ntohl (mp->retval);
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->result_ready = 1;
2226     }
2227 }
2228
2229 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2230   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   vat_json_node_t node;
2234
2235   vat_json_init_object (&node);
2236   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2237   vat_json_object_add_uint (&node, "fwd_entry_index",
2238                             clib_net_to_host_u32 (mp->fwd_entry_index));
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 u8 *
2248 format_lisp_transport_protocol (u8 * s, va_list * args)
2249 {
2250   u32 proto = va_arg (*args, u32);
2251
2252   switch (proto)
2253     {
2254     case 1:
2255       return format (s, "udp");
2256     case 2:
2257       return format (s, "api");
2258     default:
2259       return 0;
2260     }
2261   return 0;
2262 }
2263
2264 static void vl_api_one_get_transport_protocol_reply_t_handler
2265   (vl_api_one_get_transport_protocol_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   i32 retval = ntohl (mp->retval);
2269   if (vam->async_mode)
2270     {
2271       vam->async_errors += (retval < 0);
2272     }
2273   else
2274     {
2275       u32 proto = mp->protocol;
2276       print (vam->ofp, "Transport protocol: %U",
2277              format_lisp_transport_protocol, proto);
2278       vam->retval = retval;
2279       vam->result_ready = 1;
2280     }
2281 }
2282
2283 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2284   (vl_api_one_get_transport_protocol_reply_t * mp)
2285 {
2286   vat_main_t *vam = &vat_main;
2287   vat_json_node_t node;
2288   u8 *s;
2289
2290   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2291   vec_add1 (s, 0);
2292
2293   vat_json_init_object (&node);
2294   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2295   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2296
2297   vec_free (s);
2298   vat_json_print (vam->ofp, &node);
2299   vat_json_free (&node);
2300
2301   vam->retval = ntohl (mp->retval);
2302   vam->result_ready = 1;
2303 }
2304
2305 static void vl_api_one_add_del_locator_set_reply_t_handler
2306   (vl_api_one_add_del_locator_set_reply_t * mp)
2307 {
2308   vat_main_t *vam = &vat_main;
2309   i32 retval = ntohl (mp->retval);
2310   if (vam->async_mode)
2311     {
2312       vam->async_errors += (retval < 0);
2313     }
2314   else
2315     {
2316       vam->retval = retval;
2317       vam->result_ready = 1;
2318     }
2319 }
2320
2321 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2322   (vl_api_one_add_del_locator_set_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t node;
2326
2327   vat_json_init_object (&node);
2328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2329   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2330
2331   vat_json_print (vam->ofp, &node);
2332   vat_json_free (&node);
2333
2334   vam->retval = ntohl (mp->retval);
2335   vam->result_ready = 1;
2336 }
2337
2338 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2339   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2340 {
2341   vat_main_t *vam = &vat_main;
2342   i32 retval = ntohl (mp->retval);
2343   if (vam->async_mode)
2344     {
2345       vam->async_errors += (retval < 0);
2346     }
2347   else
2348     {
2349       vam->retval = retval;
2350       vam->sw_if_index = ntohl (mp->sw_if_index);
2351       vam->result_ready = 1;
2352     }
2353   vam->regenerate_interface_table = 1;
2354 }
2355
2356 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2357   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   vat_json_node_t node;
2361
2362   vat_json_init_object (&node);
2363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2364   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2365
2366   vat_json_print (vam->ofp, &node);
2367   vat_json_free (&node);
2368
2369   vam->retval = ntohl (mp->retval);
2370   vam->result_ready = 1;
2371 }
2372
2373 static void vl_api_vxlan_offload_rx_reply_t_handler
2374   (vl_api_vxlan_offload_rx_reply_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   i32 retval = ntohl (mp->retval);
2378   if (vam->async_mode)
2379     {
2380       vam->async_errors += (retval < 0);
2381     }
2382   else
2383     {
2384       vam->retval = retval;
2385       vam->result_ready = 1;
2386     }
2387 }
2388
2389 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2390   (vl_api_vxlan_offload_rx_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   vat_json_node_t node;
2394
2395   vat_json_init_object (&node);
2396   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2397
2398   vat_json_print (vam->ofp, &node);
2399   vat_json_free (&node);
2400
2401   vam->retval = ntohl (mp->retval);
2402   vam->result_ready = 1;
2403 }
2404
2405 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2406   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   i32 retval = ntohl (mp->retval);
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->sw_if_index = ntohl (mp->sw_if_index);
2418       vam->result_ready = 1;
2419     }
2420 }
2421
2422 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2423   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   vat_json_node_t node;
2427
2428   vat_json_init_object (&node);
2429   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2430   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2431
2432   vat_json_print (vam->ofp, &node);
2433   vat_json_free (&node);
2434
2435   vam->retval = ntohl (mp->retval);
2436   vam->result_ready = 1;
2437 }
2438
2439 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2440   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   i32 retval = ntohl (mp->retval);
2444   if (vam->async_mode)
2445     {
2446       vam->async_errors += (retval < 0);
2447     }
2448   else
2449     {
2450       vam->retval = retval;
2451       vam->sw_if_index = ntohl (mp->sw_if_index);
2452       vam->result_ready = 1;
2453     }
2454   vam->regenerate_interface_table = 1;
2455 }
2456
2457 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2458   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2459 {
2460   vat_main_t *vam = &vat_main;
2461   vat_json_node_t node;
2462
2463   vat_json_init_object (&node);
2464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2466
2467   vat_json_print (vam->ofp, &node);
2468   vat_json_free (&node);
2469
2470   vam->retval = ntohl (mp->retval);
2471   vam->result_ready = 1;
2472 }
2473
2474 static void vl_api_gre_tunnel_add_del_reply_t_handler
2475   (vl_api_gre_tunnel_add_del_reply_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   i32 retval = ntohl (mp->retval);
2479   if (vam->async_mode)
2480     {
2481       vam->async_errors += (retval < 0);
2482     }
2483   else
2484     {
2485       vam->retval = retval;
2486       vam->sw_if_index = ntohl (mp->sw_if_index);
2487       vam->result_ready = 1;
2488     }
2489 }
2490
2491 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2492   (vl_api_gre_tunnel_add_del_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   vat_json_node_t node;
2496
2497   vat_json_init_object (&node);
2498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2499   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_create_vhost_user_if_reply_t_handler
2509   (vl_api_create_vhost_user_if_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   i32 retval = ntohl (mp->retval);
2513   if (vam->async_mode)
2514     {
2515       vam->async_errors += (retval < 0);
2516     }
2517   else
2518     {
2519       vam->retval = retval;
2520       vam->sw_if_index = ntohl (mp->sw_if_index);
2521       vam->result_ready = 1;
2522     }
2523   vam->regenerate_interface_table = 1;
2524 }
2525
2526 static void vl_api_create_vhost_user_if_reply_t_handler_json
2527   (vl_api_create_vhost_user_if_reply_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   vat_json_node_t node;
2531
2532   vat_json_init_object (&node);
2533   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2534   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2535
2536   vat_json_print (vam->ofp, &node);
2537   vat_json_free (&node);
2538
2539   vam->retval = ntohl (mp->retval);
2540   vam->result_ready = 1;
2541 }
2542
2543 static void vl_api_dns_resolve_name_reply_t_handler
2544   (vl_api_dns_resolve_name_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   i32 retval = ntohl (mp->retval);
2548   if (vam->async_mode)
2549     {
2550       vam->async_errors += (retval < 0);
2551     }
2552   else
2553     {
2554       vam->retval = retval;
2555       vam->result_ready = 1;
2556
2557       if (retval == 0)
2558         {
2559           if (mp->ip4_set)
2560             clib_warning ("ip4 address %U", format_ip4_address,
2561                           (ip4_address_t *) mp->ip4_address);
2562           if (mp->ip6_set)
2563             clib_warning ("ip6 address %U", format_ip6_address,
2564                           (ip6_address_t *) mp->ip6_address);
2565         }
2566       else
2567         clib_warning ("retval %d", retval);
2568     }
2569 }
2570
2571 static void vl_api_dns_resolve_name_reply_t_handler_json
2572   (vl_api_dns_resolve_name_reply_t * mp)
2573 {
2574   clib_warning ("not implemented");
2575 }
2576
2577 static void vl_api_dns_resolve_ip_reply_t_handler
2578   (vl_api_dns_resolve_ip_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   i32 retval = ntohl (mp->retval);
2582   if (vam->async_mode)
2583     {
2584       vam->async_errors += (retval < 0);
2585     }
2586   else
2587     {
2588       vam->retval = retval;
2589       vam->result_ready = 1;
2590
2591       if (retval == 0)
2592         {
2593           clib_warning ("canonical name %s", mp->name);
2594         }
2595       else
2596         clib_warning ("retval %d", retval);
2597     }
2598 }
2599
2600 static void vl_api_dns_resolve_ip_reply_t_handler_json
2601   (vl_api_dns_resolve_ip_reply_t * mp)
2602 {
2603   clib_warning ("not implemented");
2604 }
2605
2606
2607 static void vl_api_ip_address_details_t_handler
2608   (vl_api_ip_address_details_t * mp)
2609 {
2610   vat_main_t *vam = &vat_main;
2611   static ip_address_details_t empty_ip_address_details = { {0} };
2612   ip_address_details_t *address = NULL;
2613   ip_details_t *current_ip_details = NULL;
2614   ip_details_t *details = NULL;
2615
2616   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2617
2618   if (!details || vam->current_sw_if_index >= vec_len (details)
2619       || !details[vam->current_sw_if_index].present)
2620     {
2621       errmsg ("ip address details arrived but not stored");
2622       errmsg ("ip_dump should be called first");
2623       return;
2624     }
2625
2626   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2627
2628 #define addresses (current_ip_details->addr)
2629
2630   vec_validate_init_empty (addresses, vec_len (addresses),
2631                            empty_ip_address_details);
2632
2633   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2634
2635   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2636   address->prefix_length = mp->prefix_length;
2637 #undef addresses
2638 }
2639
2640 static void vl_api_ip_address_details_t_handler_json
2641   (vl_api_ip_address_details_t * mp)
2642 {
2643   vat_main_t *vam = &vat_main;
2644   vat_json_node_t *node = NULL;
2645   struct in6_addr ip6;
2646   struct in_addr ip4;
2647
2648   if (VAT_JSON_ARRAY != vam->json_tree.type)
2649     {
2650       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2651       vat_json_init_array (&vam->json_tree);
2652     }
2653   node = vat_json_array_add (&vam->json_tree);
2654
2655   vat_json_init_object (node);
2656   if (vam->is_ipv6)
2657     {
2658       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2659       vat_json_object_add_ip6 (node, "ip", ip6);
2660     }
2661   else
2662     {
2663       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2664       vat_json_object_add_ip4 (node, "ip", ip4);
2665     }
2666   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2667 }
2668
2669 static void
2670 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2671 {
2672   vat_main_t *vam = &vat_main;
2673   static ip_details_t empty_ip_details = { 0 };
2674   ip_details_t *ip = NULL;
2675   u32 sw_if_index = ~0;
2676
2677   sw_if_index = ntohl (mp->sw_if_index);
2678
2679   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2680                            sw_if_index, empty_ip_details);
2681
2682   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2683                          sw_if_index);
2684
2685   ip->present = 1;
2686 }
2687
2688 static void
2689 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2690 {
2691   vat_main_t *vam = &vat_main;
2692
2693   if (VAT_JSON_ARRAY != vam->json_tree.type)
2694     {
2695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2696       vat_json_init_array (&vam->json_tree);
2697     }
2698   vat_json_array_add_uint (&vam->json_tree,
2699                            clib_net_to_host_u32 (mp->sw_if_index));
2700 }
2701
2702 static void
2703 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2704 {
2705   u8 *s, i;
2706
2707   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2708               "host_mac %U router_addr %U",
2709               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2710               mp->lease.hostname,
2711               format_ip4_address, mp->lease.host_address,
2712               format_ethernet_address, mp->lease.host_mac,
2713               format_ip4_address, mp->lease.router_address);
2714
2715   for (i = 0; i < mp->lease.count; i++)
2716     s =
2717       format (s, " domain_server_addr %U", format_ip4_address,
2718               mp->lease.domain_server[i].address);
2719
2720   errmsg ((char *) s);
2721   vec_free (s);
2722 }
2723
2724 static void vl_api_dhcp_compl_event_t_handler_json
2725   (vl_api_dhcp_compl_event_t * mp)
2726 {
2727   /* JSON output not supported */
2728 }
2729
2730 static void vl_api_get_first_msg_id_reply_t_handler
2731   (vl_api_get_first_msg_id_reply_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   i32 retval = ntohl (mp->retval);
2735
2736   if (vam->async_mode)
2737     {
2738       vam->async_errors += (retval < 0);
2739     }
2740   else
2741     {
2742       vam->retval = retval;
2743       vam->result_ready = 1;
2744     }
2745   if (retval >= 0)
2746     {
2747       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2748     }
2749 }
2750
2751 static void vl_api_get_first_msg_id_reply_t_handler_json
2752   (vl_api_get_first_msg_id_reply_t * mp)
2753 {
2754   vat_main_t *vam = &vat_main;
2755   vat_json_node_t node;
2756
2757   vat_json_init_object (&node);
2758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2759   vat_json_object_add_uint (&node, "first_msg_id",
2760                             (uint) ntohs (mp->first_msg_id));
2761
2762   vat_json_print (vam->ofp, &node);
2763   vat_json_free (&node);
2764
2765   vam->retval = ntohl (mp->retval);
2766   vam->result_ready = 1;
2767 }
2768
2769 static void vl_api_get_node_graph_reply_t_handler
2770   (vl_api_get_node_graph_reply_t * mp)
2771 {
2772   vat_main_t *vam = &vat_main;
2773   api_main_t *am = &api_main;
2774   i32 retval = ntohl (mp->retval);
2775   u8 *pvt_copy, *reply;
2776   void *oldheap;
2777   vlib_node_t *node;
2778   int i;
2779
2780   if (vam->async_mode)
2781     {
2782       vam->async_errors += (retval < 0);
2783     }
2784   else
2785     {
2786       vam->retval = retval;
2787       vam->result_ready = 1;
2788     }
2789
2790   /* "Should never happen..." */
2791   if (retval != 0)
2792     return;
2793
2794   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2795   pvt_copy = vec_dup (reply);
2796
2797   /* Toss the shared-memory original... */
2798   pthread_mutex_lock (&am->vlib_rp->mutex);
2799   oldheap = svm_push_data_heap (am->vlib_rp);
2800
2801   vec_free (reply);
2802
2803   svm_pop_heap (oldheap);
2804   pthread_mutex_unlock (&am->vlib_rp->mutex);
2805
2806   if (vam->graph_nodes)
2807     {
2808       hash_free (vam->graph_node_index_by_name);
2809
2810       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2811         {
2812           node = vam->graph_nodes[0][i];
2813           vec_free (node->name);
2814           vec_free (node->next_nodes);
2815           vec_free (node);
2816         }
2817       vec_free (vam->graph_nodes[0]);
2818       vec_free (vam->graph_nodes);
2819     }
2820
2821   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2822   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2823   vec_free (pvt_copy);
2824
2825   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2826     {
2827       node = vam->graph_nodes[0][i];
2828       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2829     }
2830 }
2831
2832 static void vl_api_get_node_graph_reply_t_handler_json
2833   (vl_api_get_node_graph_reply_t * mp)
2834 {
2835   vat_main_t *vam = &vat_main;
2836   api_main_t *am = &api_main;
2837   void *oldheap;
2838   vat_json_node_t node;
2839   u8 *reply;
2840
2841   /* $$$$ make this real? */
2842   vat_json_init_object (&node);
2843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2844   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2845
2846   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2847
2848   /* Toss the shared-memory original... */
2849   pthread_mutex_lock (&am->vlib_rp->mutex);
2850   oldheap = svm_push_data_heap (am->vlib_rp);
2851
2852   vec_free (reply);
2853
2854   svm_pop_heap (oldheap);
2855   pthread_mutex_unlock (&am->vlib_rp->mutex);
2856
2857   vat_json_print (vam->ofp, &node);
2858   vat_json_free (&node);
2859
2860   vam->retval = ntohl (mp->retval);
2861   vam->result_ready = 1;
2862 }
2863
2864 static void
2865 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2866 {
2867   vat_main_t *vam = &vat_main;
2868   u8 *s = 0;
2869
2870   if (mp->local)
2871     {
2872       s = format (s, "%=16d%=16d%=16d",
2873                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2874     }
2875   else
2876     {
2877       s = format (s, "%=16U%=16d%=16d",
2878                   mp->is_ipv6 ? format_ip6_address :
2879                   format_ip4_address,
2880                   mp->ip_address, mp->priority, mp->weight);
2881     }
2882
2883   print (vam->ofp, "%v", s);
2884   vec_free (s);
2885 }
2886
2887 static void
2888 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892   struct in6_addr ip6;
2893   struct in_addr ip4;
2894
2895   if (VAT_JSON_ARRAY != vam->json_tree.type)
2896     {
2897       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2898       vat_json_init_array (&vam->json_tree);
2899     }
2900   node = vat_json_array_add (&vam->json_tree);
2901   vat_json_init_object (node);
2902
2903   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2904   vat_json_object_add_uint (node, "priority", mp->priority);
2905   vat_json_object_add_uint (node, "weight", mp->weight);
2906
2907   if (mp->local)
2908     vat_json_object_add_uint (node, "sw_if_index",
2909                               clib_net_to_host_u32 (mp->sw_if_index));
2910   else
2911     {
2912       if (mp->is_ipv6)
2913         {
2914           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2915           vat_json_object_add_ip6 (node, "address", ip6);
2916         }
2917       else
2918         {
2919           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2920           vat_json_object_add_ip4 (node, "address", ip4);
2921         }
2922     }
2923 }
2924
2925 static void
2926 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2927                                           mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *ls_name = 0;
2931
2932   ls_name = format (0, "%s", mp->ls_name);
2933
2934   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2935          ls_name);
2936   vec_free (ls_name);
2937 }
2938
2939 static void
2940   vl_api_one_locator_set_details_t_handler_json
2941   (vl_api_one_locator_set_details_t * mp)
2942 {
2943   vat_main_t *vam = &vat_main;
2944   vat_json_node_t *node = 0;
2945   u8 *ls_name = 0;
2946
2947   ls_name = format (0, "%s", mp->ls_name);
2948   vec_add1 (ls_name, 0);
2949
2950   if (VAT_JSON_ARRAY != vam->json_tree.type)
2951     {
2952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2953       vat_json_init_array (&vam->json_tree);
2954     }
2955   node = vat_json_array_add (&vam->json_tree);
2956
2957   vat_json_init_object (node);
2958   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2959   vat_json_object_add_uint (node, "ls_index",
2960                             clib_net_to_host_u32 (mp->ls_index));
2961   vec_free (ls_name);
2962 }
2963
2964 typedef struct
2965 {
2966   u32 spi;
2967   u8 si;
2968 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2969
2970 uword
2971 unformat_nsh_address (unformat_input_t * input, va_list * args)
2972 {
2973   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2974   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2975 }
2976
2977 u8 *
2978 format_nsh_address_vat (u8 * s, va_list * args)
2979 {
2980   nsh_t *a = va_arg (*args, nsh_t *);
2981   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2982 }
2983
2984 static u8 *
2985 format_lisp_flat_eid (u8 * s, va_list * args)
2986 {
2987   u32 type = va_arg (*args, u32);
2988   u8 *eid = va_arg (*args, u8 *);
2989   u32 eid_len = va_arg (*args, u32);
2990
2991   switch (type)
2992     {
2993     case 0:
2994       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2995     case 1:
2996       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2997     case 2:
2998       return format (s, "%U", format_ethernet_address, eid);
2999     case 3:
3000       return format (s, "%U", format_nsh_address_vat, eid);
3001     }
3002   return 0;
3003 }
3004
3005 static u8 *
3006 format_lisp_eid_vat (u8 * s, va_list * args)
3007 {
3008   u32 type = va_arg (*args, u32);
3009   u8 *eid = va_arg (*args, u8 *);
3010   u32 eid_len = va_arg (*args, u32);
3011   u8 *seid = va_arg (*args, u8 *);
3012   u32 seid_len = va_arg (*args, u32);
3013   u32 is_src_dst = va_arg (*args, u32);
3014
3015   if (is_src_dst)
3016     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3017
3018   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3019
3020   return s;
3021 }
3022
3023 static void
3024 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3025 {
3026   vat_main_t *vam = &vat_main;
3027   u8 *s = 0, *eid = 0;
3028
3029   if (~0 == mp->locator_set_index)
3030     s = format (0, "action: %d", mp->action);
3031   else
3032     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3033
3034   eid = format (0, "%U", format_lisp_eid_vat,
3035                 mp->eid_type,
3036                 mp->eid,
3037                 mp->eid_prefix_len,
3038                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3039   vec_add1 (eid, 0);
3040
3041   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3042          clib_net_to_host_u32 (mp->vni),
3043          eid,
3044          mp->is_local ? "local" : "remote",
3045          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3046          clib_net_to_host_u16 (mp->key_id), mp->key);
3047
3048   vec_free (s);
3049   vec_free (eid);
3050 }
3051
3052 static void
3053 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3054                                              * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t *node = 0;
3058   u8 *eid = 0;
3059
3060   if (VAT_JSON_ARRAY != vam->json_tree.type)
3061     {
3062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3063       vat_json_init_array (&vam->json_tree);
3064     }
3065   node = vat_json_array_add (&vam->json_tree);
3066
3067   vat_json_init_object (node);
3068   if (~0 == mp->locator_set_index)
3069     vat_json_object_add_uint (node, "action", mp->action);
3070   else
3071     vat_json_object_add_uint (node, "locator_set_index",
3072                               clib_net_to_host_u32 (mp->locator_set_index));
3073
3074   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3075   if (mp->eid_type == 3)
3076     {
3077       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3078       vat_json_init_object (nsh_json);
3079       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3080       vat_json_object_add_uint (nsh_json, "spi",
3081                                 clib_net_to_host_u32 (nsh->spi));
3082       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3083     }
3084   else
3085     {
3086       eid = format (0, "%U", format_lisp_eid_vat,
3087                     mp->eid_type,
3088                     mp->eid,
3089                     mp->eid_prefix_len,
3090                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3091       vec_add1 (eid, 0);
3092       vat_json_object_add_string_copy (node, "eid", eid);
3093       vec_free (eid);
3094     }
3095   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3096   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3097   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3098
3099   if (mp->key_id)
3100     {
3101       vat_json_object_add_uint (node, "key_id",
3102                                 clib_net_to_host_u16 (mp->key_id));
3103       vat_json_object_add_string_copy (node, "key", mp->key);
3104     }
3105 }
3106
3107 static void
3108 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u8 *seid = 0, *deid = 0;
3112   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3113
3114   deid = format (0, "%U", format_lisp_eid_vat,
3115                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3116
3117   seid = format (0, "%U", format_lisp_eid_vat,
3118                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3119
3120   vec_add1 (deid, 0);
3121   vec_add1 (seid, 0);
3122
3123   if (mp->is_ip4)
3124     format_ip_address_fcn = format_ip4_address;
3125   else
3126     format_ip_address_fcn = format_ip6_address;
3127
3128
3129   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3130          clib_net_to_host_u32 (mp->vni),
3131          seid, deid,
3132          format_ip_address_fcn, mp->lloc,
3133          format_ip_address_fcn, mp->rloc,
3134          clib_net_to_host_u32 (mp->pkt_count),
3135          clib_net_to_host_u32 (mp->bytes));
3136
3137   vec_free (deid);
3138   vec_free (seid);
3139 }
3140
3141 static void
3142 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3143 {
3144   struct in6_addr ip6;
3145   struct in_addr ip4;
3146   vat_main_t *vam = &vat_main;
3147   vat_json_node_t *node = 0;
3148   u8 *deid = 0, *seid = 0;
3149
3150   if (VAT_JSON_ARRAY != vam->json_tree.type)
3151     {
3152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3153       vat_json_init_array (&vam->json_tree);
3154     }
3155   node = vat_json_array_add (&vam->json_tree);
3156
3157   vat_json_init_object (node);
3158   deid = format (0, "%U", format_lisp_eid_vat,
3159                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3160
3161   seid = format (0, "%U", format_lisp_eid_vat,
3162                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3163
3164   vec_add1 (deid, 0);
3165   vec_add1 (seid, 0);
3166
3167   vat_json_object_add_string_copy (node, "seid", seid);
3168   vat_json_object_add_string_copy (node, "deid", deid);
3169   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3170
3171   if (mp->is_ip4)
3172     {
3173       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3174       vat_json_object_add_ip4 (node, "lloc", ip4);
3175       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3176       vat_json_object_add_ip4 (node, "rloc", ip4);
3177     }
3178   else
3179     {
3180       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3181       vat_json_object_add_ip6 (node, "lloc", ip6);
3182       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3183       vat_json_object_add_ip6 (node, "rloc", ip6);
3184     }
3185   vat_json_object_add_uint (node, "pkt_count",
3186                             clib_net_to_host_u32 (mp->pkt_count));
3187   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3188
3189   vec_free (deid);
3190   vec_free (seid);
3191 }
3192
3193 static void
3194   vl_api_one_eid_table_map_details_t_handler
3195   (vl_api_one_eid_table_map_details_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198
3199   u8 *line = format (0, "%=10d%=10d",
3200                      clib_net_to_host_u32 (mp->vni),
3201                      clib_net_to_host_u32 (mp->dp_table));
3202   print (vam->ofp, "%v", line);
3203   vec_free (line);
3204 }
3205
3206 static void
3207   vl_api_one_eid_table_map_details_t_handler_json
3208   (vl_api_one_eid_table_map_details_t * mp)
3209 {
3210   vat_main_t *vam = &vat_main;
3211   vat_json_node_t *node = NULL;
3212
3213   if (VAT_JSON_ARRAY != vam->json_tree.type)
3214     {
3215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3216       vat_json_init_array (&vam->json_tree);
3217     }
3218   node = vat_json_array_add (&vam->json_tree);
3219   vat_json_init_object (node);
3220   vat_json_object_add_uint (node, "dp_table",
3221                             clib_net_to_host_u32 (mp->dp_table));
3222   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3223 }
3224
3225 static void
3226   vl_api_one_eid_table_vni_details_t_handler
3227   (vl_api_one_eid_table_vni_details_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230
3231   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3232   print (vam->ofp, "%v", line);
3233   vec_free (line);
3234 }
3235
3236 static void
3237   vl_api_one_eid_table_vni_details_t_handler_json
3238   (vl_api_one_eid_table_vni_details_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241   vat_json_node_t *node = NULL;
3242
3243   if (VAT_JSON_ARRAY != vam->json_tree.type)
3244     {
3245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3246       vat_json_init_array (&vam->json_tree);
3247     }
3248   node = vat_json_array_add (&vam->json_tree);
3249   vat_json_init_object (node);
3250   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3251 }
3252
3253 static void
3254   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3255   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   int retval = clib_net_to_host_u32 (mp->retval);
3259
3260   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3261   print (vam->ofp, "fallback threshold value: %d", mp->value);
3262
3263   vam->retval = retval;
3264   vam->result_ready = 1;
3265 }
3266
3267 static void
3268   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3269   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272   vat_json_node_t _node, *node = &_node;
3273   int retval = clib_net_to_host_u32 (mp->retval);
3274
3275   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3276   vat_json_init_object (node);
3277   vat_json_object_add_uint (node, "value", mp->value);
3278
3279   vat_json_print (vam->ofp, node);
3280   vat_json_free (node);
3281
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284 }
3285
3286 static void
3287   vl_api_show_one_map_register_state_reply_t_handler
3288   (vl_api_show_one_map_register_state_reply_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3294
3295   vam->retval = retval;
3296   vam->result_ready = 1;
3297 }
3298
3299 static void
3300   vl_api_show_one_map_register_state_reply_t_handler_json
3301   (vl_api_show_one_map_register_state_reply_t * mp)
3302 {
3303   vat_main_t *vam = &vat_main;
3304   vat_json_node_t _node, *node = &_node;
3305   int retval = clib_net_to_host_u32 (mp->retval);
3306
3307   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3308
3309   vat_json_init_object (node);
3310   vat_json_object_add_string_copy (node, "state", s);
3311
3312   vat_json_print (vam->ofp, node);
3313   vat_json_free (node);
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317   vec_free (s);
3318 }
3319
3320 static void
3321   vl_api_show_one_rloc_probe_state_reply_t_handler
3322   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3323 {
3324   vat_main_t *vam = &vat_main;
3325   int retval = clib_net_to_host_u32 (mp->retval);
3326
3327   if (retval)
3328     goto end;
3329
3330   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3331 end:
3332   vam->retval = retval;
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3338   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   vat_json_node_t _node, *node = &_node;
3342   int retval = clib_net_to_host_u32 (mp->retval);
3343
3344   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3345   vat_json_init_object (node);
3346   vat_json_object_add_string_copy (node, "state", s);
3347
3348   vat_json_print (vam->ofp, node);
3349   vat_json_free (node);
3350
3351   vam->retval = retval;
3352   vam->result_ready = 1;
3353   vec_free (s);
3354 }
3355
3356 static void
3357   vl_api_show_one_stats_enable_disable_reply_t_handler
3358   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   if (retval)
3364     goto end;
3365
3366   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3367 end:
3368   vam->retval = retval;
3369   vam->result_ready = 1;
3370 }
3371
3372 static void
3373   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3374   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3375 {
3376   vat_main_t *vam = &vat_main;
3377   vat_json_node_t _node, *node = &_node;
3378   int retval = clib_net_to_host_u32 (mp->retval);
3379
3380   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3381   vat_json_init_object (node);
3382   vat_json_object_add_string_copy (node, "state", s);
3383
3384   vat_json_print (vam->ofp, node);
3385   vat_json_free (node);
3386
3387   vam->retval = retval;
3388   vam->result_ready = 1;
3389   vec_free (s);
3390 }
3391
3392 static void
3393 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3394 {
3395   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3396   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3397   e->vni = clib_net_to_host_u32 (e->vni);
3398 }
3399
3400 static void
3401   gpe_fwd_entries_get_reply_t_net_to_host
3402   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3403 {
3404   u32 i;
3405
3406   mp->count = clib_net_to_host_u32 (mp->count);
3407   for (i = 0; i < mp->count; i++)
3408     {
3409       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3410     }
3411 }
3412
3413 static u8 *
3414 format_gpe_encap_mode (u8 * s, va_list * args)
3415 {
3416   u32 mode = va_arg (*args, u32);
3417
3418   switch (mode)
3419     {
3420     case 0:
3421       return format (s, "lisp");
3422     case 1:
3423       return format (s, "vxlan");
3424     }
3425   return 0;
3426 }
3427
3428 static void
3429   vl_api_gpe_get_encap_mode_reply_t_handler
3430   (vl_api_gpe_get_encap_mode_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3435   vam->retval = ntohl (mp->retval);
3436   vam->result_ready = 1;
3437 }
3438
3439 static void
3440   vl_api_gpe_get_encap_mode_reply_t_handler_json
3441   (vl_api_gpe_get_encap_mode_reply_t * mp)
3442 {
3443   vat_main_t *vam = &vat_main;
3444   vat_json_node_t node;
3445
3446   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3447   vec_add1 (encap_mode, 0);
3448
3449   vat_json_init_object (&node);
3450   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3451
3452   vec_free (encap_mode);
3453   vat_json_print (vam->ofp, &node);
3454   vat_json_free (&node);
3455
3456   vam->retval = ntohl (mp->retval);
3457   vam->result_ready = 1;
3458 }
3459
3460 static void
3461   vl_api_gpe_fwd_entry_path_details_t_handler
3462   (vl_api_gpe_fwd_entry_path_details_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3466
3467   if (mp->lcl_loc.is_ip4)
3468     format_ip_address_fcn = format_ip4_address;
3469   else
3470     format_ip_address_fcn = format_ip6_address;
3471
3472   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3473          format_ip_address_fcn, &mp->lcl_loc,
3474          format_ip_address_fcn, &mp->rmt_loc);
3475 }
3476
3477 static void
3478 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3479 {
3480   struct in6_addr ip6;
3481   struct in_addr ip4;
3482
3483   if (loc->is_ip4)
3484     {
3485       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3486       vat_json_object_add_ip4 (n, "address", ip4);
3487     }
3488   else
3489     {
3490       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3491       vat_json_object_add_ip6 (n, "address", ip6);
3492     }
3493   vat_json_object_add_uint (n, "weight", loc->weight);
3494 }
3495
3496 static void
3497   vl_api_gpe_fwd_entry_path_details_t_handler_json
3498   (vl_api_gpe_fwd_entry_path_details_t * mp)
3499 {
3500   vat_main_t *vam = &vat_main;
3501   vat_json_node_t *node = NULL;
3502   vat_json_node_t *loc_node;
3503
3504   if (VAT_JSON_ARRAY != vam->json_tree.type)
3505     {
3506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3507       vat_json_init_array (&vam->json_tree);
3508     }
3509   node = vat_json_array_add (&vam->json_tree);
3510   vat_json_init_object (node);
3511
3512   loc_node = vat_json_object_add (node, "local_locator");
3513   vat_json_init_object (loc_node);
3514   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3515
3516   loc_node = vat_json_object_add (node, "remote_locator");
3517   vat_json_init_object (loc_node);
3518   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3519 }
3520
3521 static void
3522   vl_api_gpe_fwd_entries_get_reply_t_handler
3523   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526   u32 i;
3527   int retval = clib_net_to_host_u32 (mp->retval);
3528   vl_api_gpe_fwd_entry_t *e;
3529
3530   if (retval)
3531     goto end;
3532
3533   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3534
3535   for (i = 0; i < mp->count; i++)
3536     {
3537       e = &mp->entries[i];
3538       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3539              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3540              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3541     }
3542
3543 end:
3544   vam->retval = retval;
3545   vam->result_ready = 1;
3546 }
3547
3548 static void
3549   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3550   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3551 {
3552   u8 *s = 0;
3553   vat_main_t *vam = &vat_main;
3554   vat_json_node_t *e = 0, root;
3555   u32 i;
3556   int retval = clib_net_to_host_u32 (mp->retval);
3557   vl_api_gpe_fwd_entry_t *fwd;
3558
3559   if (retval)
3560     goto end;
3561
3562   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3563   vat_json_init_array (&root);
3564
3565   for (i = 0; i < mp->count; i++)
3566     {
3567       e = vat_json_array_add (&root);
3568       fwd = &mp->entries[i];
3569
3570       vat_json_init_object (e);
3571       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3572       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3573       vat_json_object_add_int (e, "vni", fwd->vni);
3574       vat_json_object_add_int (e, "action", fwd->action);
3575
3576       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3577                   fwd->leid_prefix_len);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "leid", s);
3580       vec_free (s);
3581
3582       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3583                   fwd->reid_prefix_len);
3584       vec_add1 (s, 0);
3585       vat_json_object_add_string_copy (e, "reid", s);
3586       vec_free (s);
3587     }
3588
3589   vat_json_print (vam->ofp, &root);
3590   vat_json_free (&root);
3591
3592 end:
3593   vam->retval = retval;
3594   vam->result_ready = 1;
3595 }
3596
3597 static void
3598   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3599   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3600 {
3601   vat_main_t *vam = &vat_main;
3602   u32 i, n;
3603   int retval = clib_net_to_host_u32 (mp->retval);
3604   vl_api_gpe_native_fwd_rpath_t *r;
3605
3606   if (retval)
3607     goto end;
3608
3609   n = clib_net_to_host_u32 (mp->count);
3610
3611   for (i = 0; i < n; i++)
3612     {
3613       r = &mp->entries[i];
3614       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3615              clib_net_to_host_u32 (r->fib_index),
3616              clib_net_to_host_u32 (r->nh_sw_if_index),
3617              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3618     }
3619
3620 end:
3621   vam->retval = retval;
3622   vam->result_ready = 1;
3623 }
3624
3625 static void
3626   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3627   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3628 {
3629   vat_main_t *vam = &vat_main;
3630   vat_json_node_t root, *e;
3631   u32 i, n;
3632   int retval = clib_net_to_host_u32 (mp->retval);
3633   vl_api_gpe_native_fwd_rpath_t *r;
3634   u8 *s;
3635
3636   if (retval)
3637     goto end;
3638
3639   n = clib_net_to_host_u32 (mp->count);
3640   vat_json_init_array (&root);
3641
3642   for (i = 0; i < n; i++)
3643     {
3644       e = vat_json_array_add (&root);
3645       vat_json_init_object (e);
3646       r = &mp->entries[i];
3647       s =
3648         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3649                 r->nh_addr);
3650       vec_add1 (s, 0);
3651       vat_json_object_add_string_copy (e, "ip4", s);
3652       vec_free (s);
3653
3654       vat_json_object_add_uint (e, "fib_index",
3655                                 clib_net_to_host_u32 (r->fib_index));
3656       vat_json_object_add_uint (e, "nh_sw_if_index",
3657                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3658     }
3659
3660   vat_json_print (vam->ofp, &root);
3661   vat_json_free (&root);
3662
3663 end:
3664   vam->retval = retval;
3665   vam->result_ready = 1;
3666 }
3667
3668 static void
3669   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3670   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3671 {
3672   vat_main_t *vam = &vat_main;
3673   u32 i, n;
3674   int retval = clib_net_to_host_u32 (mp->retval);
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3683
3684 end:
3685   vam->retval = retval;
3686   vam->result_ready = 1;
3687 }
3688
3689 static void
3690   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3691   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3692 {
3693   vat_main_t *vam = &vat_main;
3694   vat_json_node_t root;
3695   u32 i, n;
3696   int retval = clib_net_to_host_u32 (mp->retval);
3697
3698   if (retval)
3699     goto end;
3700
3701   n = clib_net_to_host_u32 (mp->count);
3702   vat_json_init_array (&root);
3703
3704   for (i = 0; i < n; i++)
3705     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3706
3707   vat_json_print (vam->ofp, &root);
3708   vat_json_free (&root);
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_one_ndp_entries_get_reply_t_handler
3717   (vl_api_one_ndp_entries_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722
3723   if (retval)
3724     goto end;
3725
3726   n = clib_net_to_host_u32 (mp->count);
3727
3728   for (i = 0; i < n; i++)
3729     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3730            format_ethernet_address, mp->entries[i].mac);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_ndp_entries_get_reply_t_handler_json
3739   (vl_api_one_ndp_entries_get_reply_t * mp)
3740 {
3741   u8 *s = 0;
3742   vat_main_t *vam = &vat_main;
3743   vat_json_node_t *e = 0, root;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746   vl_api_one_ndp_entry_t *arp_entry;
3747
3748   if (retval)
3749     goto end;
3750
3751   n = clib_net_to_host_u32 (mp->count);
3752   vat_json_init_array (&root);
3753
3754   for (i = 0; i < n; i++)
3755     {
3756       e = vat_json_array_add (&root);
3757       arp_entry = &mp->entries[i];
3758
3759       vat_json_init_object (e);
3760       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3761       vec_add1 (s, 0);
3762
3763       vat_json_object_add_string_copy (e, "mac", s);
3764       vec_free (s);
3765
3766       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3767       vec_add1 (s, 0);
3768       vat_json_object_add_string_copy (e, "ip6", s);
3769       vec_free (s);
3770     }
3771
3772   vat_json_print (vam->ofp, &root);
3773   vat_json_free (&root);
3774
3775 end:
3776   vam->retval = retval;
3777   vam->result_ready = 1;
3778 }
3779
3780 static void
3781   vl_api_one_l2_arp_entries_get_reply_t_handler
3782   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3783 {
3784   vat_main_t *vam = &vat_main;
3785   u32 i, n;
3786   int retval = clib_net_to_host_u32 (mp->retval);
3787
3788   if (retval)
3789     goto end;
3790
3791   n = clib_net_to_host_u32 (mp->count);
3792
3793   for (i = 0; i < n; i++)
3794     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3795            format_ethernet_address, mp->entries[i].mac);
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3804   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3805 {
3806   u8 *s = 0;
3807   vat_main_t *vam = &vat_main;
3808   vat_json_node_t *e = 0, root;
3809   u32 i, n;
3810   int retval = clib_net_to_host_u32 (mp->retval);
3811   vl_api_one_l2_arp_entry_t *arp_entry;
3812
3813   if (retval)
3814     goto end;
3815
3816   n = clib_net_to_host_u32 (mp->count);
3817   vat_json_init_array (&root);
3818
3819   for (i = 0; i < n; i++)
3820     {
3821       e = vat_json_array_add (&root);
3822       arp_entry = &mp->entries[i];
3823
3824       vat_json_init_object (e);
3825       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3826       vec_add1 (s, 0);
3827
3828       vat_json_object_add_string_copy (e, "mac", s);
3829       vec_free (s);
3830
3831       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3832       vec_add1 (s, 0);
3833       vat_json_object_add_string_copy (e, "ip4", s);
3834       vec_free (s);
3835     }
3836
3837   vat_json_print (vam->ofp, &root);
3838   vat_json_free (&root);
3839
3840 end:
3841   vam->retval = retval;
3842   vam->result_ready = 1;
3843 }
3844
3845 static void
3846 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3847 {
3848   vat_main_t *vam = &vat_main;
3849   u32 i, n;
3850   int retval = clib_net_to_host_u32 (mp->retval);
3851
3852   if (retval)
3853     goto end;
3854
3855   n = clib_net_to_host_u32 (mp->count);
3856
3857   for (i = 0; i < n; i++)
3858     {
3859       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3860     }
3861
3862 end:
3863   vam->retval = retval;
3864   vam->result_ready = 1;
3865 }
3866
3867 static void
3868   vl_api_one_ndp_bd_get_reply_t_handler_json
3869   (vl_api_one_ndp_bd_get_reply_t * mp)
3870 {
3871   vat_main_t *vam = &vat_main;
3872   vat_json_node_t root;
3873   u32 i, n;
3874   int retval = clib_net_to_host_u32 (mp->retval);
3875
3876   if (retval)
3877     goto end;
3878
3879   n = clib_net_to_host_u32 (mp->count);
3880   vat_json_init_array (&root);
3881
3882   for (i = 0; i < n; i++)
3883     {
3884       vat_json_array_add_uint (&root,
3885                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3886     }
3887
3888   vat_json_print (vam->ofp, &root);
3889   vat_json_free (&root);
3890
3891 end:
3892   vam->retval = retval;
3893   vam->result_ready = 1;
3894 }
3895
3896 static void
3897   vl_api_one_l2_arp_bd_get_reply_t_handler
3898   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3899 {
3900   vat_main_t *vam = &vat_main;
3901   u32 i, n;
3902   int retval = clib_net_to_host_u32 (mp->retval);
3903
3904   if (retval)
3905     goto end;
3906
3907   n = clib_net_to_host_u32 (mp->count);
3908
3909   for (i = 0; i < n; i++)
3910     {
3911       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3912     }
3913
3914 end:
3915   vam->retval = retval;
3916   vam->result_ready = 1;
3917 }
3918
3919 static void
3920   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3921   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3922 {
3923   vat_main_t *vam = &vat_main;
3924   vat_json_node_t root;
3925   u32 i, n;
3926   int retval = clib_net_to_host_u32 (mp->retval);
3927
3928   if (retval)
3929     goto end;
3930
3931   n = clib_net_to_host_u32 (mp->count);
3932   vat_json_init_array (&root);
3933
3934   for (i = 0; i < n; i++)
3935     {
3936       vat_json_array_add_uint (&root,
3937                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3938     }
3939
3940   vat_json_print (vam->ofp, &root);
3941   vat_json_free (&root);
3942
3943 end:
3944   vam->retval = retval;
3945   vam->result_ready = 1;
3946 }
3947
3948 static void
3949   vl_api_one_adjacencies_get_reply_t_handler
3950   (vl_api_one_adjacencies_get_reply_t * mp)
3951 {
3952   vat_main_t *vam = &vat_main;
3953   u32 i, n;
3954   int retval = clib_net_to_host_u32 (mp->retval);
3955   vl_api_one_adjacency_t *a;
3956
3957   if (retval)
3958     goto end;
3959
3960   n = clib_net_to_host_u32 (mp->count);
3961
3962   for (i = 0; i < n; i++)
3963     {
3964       a = &mp->adjacencies[i];
3965       print (vam->ofp, "%U %40U",
3966              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3967              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3968     }
3969
3970 end:
3971   vam->retval = retval;
3972   vam->result_ready = 1;
3973 }
3974
3975 static void
3976   vl_api_one_adjacencies_get_reply_t_handler_json
3977   (vl_api_one_adjacencies_get_reply_t * mp)
3978 {
3979   u8 *s = 0;
3980   vat_main_t *vam = &vat_main;
3981   vat_json_node_t *e = 0, root;
3982   u32 i, n;
3983   int retval = clib_net_to_host_u32 (mp->retval);
3984   vl_api_one_adjacency_t *a;
3985
3986   if (retval)
3987     goto end;
3988
3989   n = clib_net_to_host_u32 (mp->count);
3990   vat_json_init_array (&root);
3991
3992   for (i = 0; i < n; i++)
3993     {
3994       e = vat_json_array_add (&root);
3995       a = &mp->adjacencies[i];
3996
3997       vat_json_init_object (e);
3998       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3999                   a->leid_prefix_len);
4000       vec_add1 (s, 0);
4001       vat_json_object_add_string_copy (e, "leid", s);
4002       vec_free (s);
4003
4004       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4005                   a->reid_prefix_len);
4006       vec_add1 (s, 0);
4007       vat_json_object_add_string_copy (e, "reid", s);
4008       vec_free (s);
4009     }
4010
4011   vat_json_print (vam->ofp, &root);
4012   vat_json_free (&root);
4013
4014 end:
4015   vam->retval = retval;
4016   vam->result_ready = 1;
4017 }
4018
4019 static void
4020 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023
4024   print (vam->ofp, "%=20U",
4025          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4026          mp->ip_address);
4027 }
4028
4029 static void
4030   vl_api_one_map_server_details_t_handler_json
4031   (vl_api_one_map_server_details_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   vat_json_node_t *node = NULL;
4035   struct in6_addr ip6;
4036   struct in_addr ip4;
4037
4038   if (VAT_JSON_ARRAY != vam->json_tree.type)
4039     {
4040       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4041       vat_json_init_array (&vam->json_tree);
4042     }
4043   node = vat_json_array_add (&vam->json_tree);
4044
4045   vat_json_init_object (node);
4046   if (mp->is_ipv6)
4047     {
4048       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4049       vat_json_object_add_ip6 (node, "map-server", ip6);
4050     }
4051   else
4052     {
4053       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4054       vat_json_object_add_ip4 (node, "map-server", ip4);
4055     }
4056 }
4057
4058 static void
4059 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4060                                            * mp)
4061 {
4062   vat_main_t *vam = &vat_main;
4063
4064   print (vam->ofp, "%=20U",
4065          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4066          mp->ip_address);
4067 }
4068
4069 static void
4070   vl_api_one_map_resolver_details_t_handler_json
4071   (vl_api_one_map_resolver_details_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   vat_json_node_t *node = NULL;
4075   struct in6_addr ip6;
4076   struct in_addr ip4;
4077
4078   if (VAT_JSON_ARRAY != vam->json_tree.type)
4079     {
4080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4081       vat_json_init_array (&vam->json_tree);
4082     }
4083   node = vat_json_array_add (&vam->json_tree);
4084
4085   vat_json_init_object (node);
4086   if (mp->is_ipv6)
4087     {
4088       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4089       vat_json_object_add_ip6 (node, "map resolver", ip6);
4090     }
4091   else
4092     {
4093       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4094       vat_json_object_add_ip4 (node, "map resolver", ip4);
4095     }
4096 }
4097
4098 static void
4099 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4100 {
4101   vat_main_t *vam = &vat_main;
4102   i32 retval = ntohl (mp->retval);
4103
4104   if (0 <= retval)
4105     {
4106       print (vam->ofp, "feature: %s\ngpe: %s",
4107              mp->feature_status ? "enabled" : "disabled",
4108              mp->gpe_status ? "enabled" : "disabled");
4109     }
4110
4111   vam->retval = retval;
4112   vam->result_ready = 1;
4113 }
4114
4115 static void
4116   vl_api_show_one_status_reply_t_handler_json
4117   (vl_api_show_one_status_reply_t * mp)
4118 {
4119   vat_main_t *vam = &vat_main;
4120   vat_json_node_t node;
4121   u8 *gpe_status = NULL;
4122   u8 *feature_status = NULL;
4123
4124   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4125   feature_status = format (0, "%s",
4126                            mp->feature_status ? "enabled" : "disabled");
4127   vec_add1 (gpe_status, 0);
4128   vec_add1 (feature_status, 0);
4129
4130   vat_json_init_object (&node);
4131   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4132   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4133
4134   vec_free (gpe_status);
4135   vec_free (feature_status);
4136
4137   vat_json_print (vam->ofp, &node);
4138   vat_json_free (&node);
4139
4140   vam->retval = ntohl (mp->retval);
4141   vam->result_ready = 1;
4142 }
4143
4144 static void
4145   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4146   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4147 {
4148   vat_main_t *vam = &vat_main;
4149   i32 retval = ntohl (mp->retval);
4150
4151   if (retval >= 0)
4152     {
4153       print (vam->ofp, "%=20s", mp->locator_set_name);
4154     }
4155
4156   vam->retval = retval;
4157   vam->result_ready = 1;
4158 }
4159
4160 static void
4161   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4162   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4163 {
4164   vat_main_t *vam = &vat_main;
4165   vat_json_node_t *node = NULL;
4166
4167   if (VAT_JSON_ARRAY != vam->json_tree.type)
4168     {
4169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4170       vat_json_init_array (&vam->json_tree);
4171     }
4172   node = vat_json_array_add (&vam->json_tree);
4173
4174   vat_json_init_object (node);
4175   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4176
4177   vat_json_print (vam->ofp, node);
4178   vat_json_free (node);
4179
4180   vam->retval = ntohl (mp->retval);
4181   vam->result_ready = 1;
4182 }
4183
4184 static u8 *
4185 format_lisp_map_request_mode (u8 * s, va_list * args)
4186 {
4187   u32 mode = va_arg (*args, u32);
4188
4189   switch (mode)
4190     {
4191     case 0:
4192       return format (0, "dst-only");
4193     case 1:
4194       return format (0, "src-dst");
4195     }
4196   return 0;
4197 }
4198
4199 static void
4200   vl_api_show_one_map_request_mode_reply_t_handler
4201   (vl_api_show_one_map_request_mode_reply_t * mp)
4202 {
4203   vat_main_t *vam = &vat_main;
4204   i32 retval = ntohl (mp->retval);
4205
4206   if (0 <= retval)
4207     {
4208       u32 mode = mp->mode;
4209       print (vam->ofp, "map_request_mode: %U",
4210              format_lisp_map_request_mode, mode);
4211     }
4212
4213   vam->retval = retval;
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_show_one_map_request_mode_reply_t_handler_json
4219   (vl_api_show_one_map_request_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   vat_json_node_t node;
4223   u8 *s = 0;
4224   u32 mode;
4225
4226   mode = mp->mode;
4227   s = format (0, "%U", format_lisp_map_request_mode, mode);
4228   vec_add1 (s, 0);
4229
4230   vat_json_init_object (&node);
4231   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4232   vat_json_print (vam->ofp, &node);
4233   vat_json_free (&node);
4234
4235   vec_free (s);
4236   vam->retval = ntohl (mp->retval);
4237   vam->result_ready = 1;
4238 }
4239
4240 static void
4241   vl_api_one_show_xtr_mode_reply_t_handler
4242   (vl_api_one_show_xtr_mode_reply_t * mp)
4243 {
4244   vat_main_t *vam = &vat_main;
4245   i32 retval = ntohl (mp->retval);
4246
4247   if (0 <= retval)
4248     {
4249       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4250     }
4251
4252   vam->retval = retval;
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_one_show_xtr_mode_reply_t_handler_json
4258   (vl_api_one_show_xtr_mode_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t node;
4262   u8 *status = 0;
4263
4264   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4265   vec_add1 (status, 0);
4266
4267   vat_json_init_object (&node);
4268   vat_json_object_add_string_copy (&node, "status", status);
4269
4270   vec_free (status);
4271
4272   vat_json_print (vam->ofp, &node);
4273   vat_json_free (&node);
4274
4275   vam->retval = ntohl (mp->retval);
4276   vam->result_ready = 1;
4277 }
4278
4279 static void
4280   vl_api_one_show_pitr_mode_reply_t_handler
4281   (vl_api_one_show_pitr_mode_reply_t * mp)
4282 {
4283   vat_main_t *vam = &vat_main;
4284   i32 retval = ntohl (mp->retval);
4285
4286   if (0 <= retval)
4287     {
4288       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4289     }
4290
4291   vam->retval = retval;
4292   vam->result_ready = 1;
4293 }
4294
4295 static void
4296   vl_api_one_show_pitr_mode_reply_t_handler_json
4297   (vl_api_one_show_pitr_mode_reply_t * mp)
4298 {
4299   vat_main_t *vam = &vat_main;
4300   vat_json_node_t node;
4301   u8 *status = 0;
4302
4303   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4304   vec_add1 (status, 0);
4305
4306   vat_json_init_object (&node);
4307   vat_json_object_add_string_copy (&node, "status", status);
4308
4309   vec_free (status);
4310
4311   vat_json_print (vam->ofp, &node);
4312   vat_json_free (&node);
4313
4314   vam->retval = ntohl (mp->retval);
4315   vam->result_ready = 1;
4316 }
4317
4318 static void
4319   vl_api_one_show_petr_mode_reply_t_handler
4320   (vl_api_one_show_petr_mode_reply_t * mp)
4321 {
4322   vat_main_t *vam = &vat_main;
4323   i32 retval = ntohl (mp->retval);
4324
4325   if (0 <= retval)
4326     {
4327       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4328     }
4329
4330   vam->retval = retval;
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_one_show_petr_mode_reply_t_handler_json
4336   (vl_api_one_show_petr_mode_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   vat_json_node_t node;
4340   u8 *status = 0;
4341
4342   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4343   vec_add1 (status, 0);
4344
4345   vat_json_init_object (&node);
4346   vat_json_object_add_string_copy (&node, "status", status);
4347
4348   vec_free (status);
4349
4350   vat_json_print (vam->ofp, &node);
4351   vat_json_free (&node);
4352
4353   vam->retval = ntohl (mp->retval);
4354   vam->result_ready = 1;
4355 }
4356
4357 static void
4358   vl_api_show_one_use_petr_reply_t_handler
4359   (vl_api_show_one_use_petr_reply_t * mp)
4360 {
4361   vat_main_t *vam = &vat_main;
4362   i32 retval = ntohl (mp->retval);
4363
4364   if (0 <= retval)
4365     {
4366       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4367       if (mp->status)
4368         {
4369           print (vam->ofp, "Proxy-ETR address; %U",
4370                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4371                  mp->address);
4372         }
4373     }
4374
4375   vam->retval = retval;
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_show_one_use_petr_reply_t_handler_json
4381   (vl_api_show_one_use_petr_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   vat_json_node_t node;
4385   u8 *status = 0;
4386   struct in_addr ip4;
4387   struct in6_addr ip6;
4388
4389   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4390   vec_add1 (status, 0);
4391
4392   vat_json_init_object (&node);
4393   vat_json_object_add_string_copy (&node, "status", status);
4394   if (mp->status)
4395     {
4396       if (mp->is_ip4)
4397         {
4398           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4399           vat_json_object_add_ip6 (&node, "address", ip6);
4400         }
4401       else
4402         {
4403           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4404           vat_json_object_add_ip4 (&node, "address", ip4);
4405         }
4406     }
4407
4408   vec_free (status);
4409
4410   vat_json_print (vam->ofp, &node);
4411   vat_json_free (&node);
4412
4413   vam->retval = ntohl (mp->retval);
4414   vam->result_ready = 1;
4415 }
4416
4417 static void
4418   vl_api_show_one_nsh_mapping_reply_t_handler
4419   (vl_api_show_one_nsh_mapping_reply_t * mp)
4420 {
4421   vat_main_t *vam = &vat_main;
4422   i32 retval = ntohl (mp->retval);
4423
4424   if (0 <= retval)
4425     {
4426       print (vam->ofp, "%-20s%-16s",
4427              mp->is_set ? "set" : "not-set",
4428              mp->is_set ? (char *) mp->locator_set_name : "");
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436   vl_api_show_one_nsh_mapping_reply_t_handler_json
4437   (vl_api_show_one_nsh_mapping_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   vat_json_node_t node;
4441   u8 *status = 0;
4442
4443   status = format (0, "%s", mp->is_set ? "yes" : "no");
4444   vec_add1 (status, 0);
4445
4446   vat_json_init_object (&node);
4447   vat_json_object_add_string_copy (&node, "is_set", status);
4448   if (mp->is_set)
4449     {
4450       vat_json_object_add_string_copy (&node, "locator_set",
4451                                        mp->locator_set_name);
4452     }
4453
4454   vec_free (status);
4455
4456   vat_json_print (vam->ofp, &node);
4457   vat_json_free (&node);
4458
4459   vam->retval = ntohl (mp->retval);
4460   vam->result_ready = 1;
4461 }
4462
4463 static void
4464   vl_api_show_one_map_register_ttl_reply_t_handler
4465   (vl_api_show_one_map_register_ttl_reply_t * mp)
4466 {
4467   vat_main_t *vam = &vat_main;
4468   i32 retval = ntohl (mp->retval);
4469
4470   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4471
4472   if (0 <= retval)
4473     {
4474       print (vam->ofp, "ttl: %u", mp->ttl);
4475     }
4476
4477   vam->retval = retval;
4478   vam->result_ready = 1;
4479 }
4480
4481 static void
4482   vl_api_show_one_map_register_ttl_reply_t_handler_json
4483   (vl_api_show_one_map_register_ttl_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   vat_json_node_t node;
4487
4488   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4489   vat_json_init_object (&node);
4490   vat_json_object_add_uint (&node, "ttl", mp->ttl);
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_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4501 {
4502   vat_main_t *vam = &vat_main;
4503   i32 retval = ntohl (mp->retval);
4504
4505   if (0 <= retval)
4506     {
4507       print (vam->ofp, "%-20s%-16s",
4508              mp->status ? "enabled" : "disabled",
4509              mp->status ? (char *) mp->locator_set_name : "");
4510     }
4511
4512   vam->retval = retval;
4513   vam->result_ready = 1;
4514 }
4515
4516 static void
4517 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   vat_json_node_t node;
4521   u8 *status = 0;
4522
4523   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4524   vec_add1 (status, 0);
4525
4526   vat_json_init_object (&node);
4527   vat_json_object_add_string_copy (&node, "status", status);
4528   if (mp->status)
4529     {
4530       vat_json_object_add_string_copy (&node, "locator_set",
4531                                        mp->locator_set_name);
4532     }
4533
4534   vec_free (status);
4535
4536   vat_json_print (vam->ofp, &node);
4537   vat_json_free (&node);
4538
4539   vam->retval = ntohl (mp->retval);
4540   vam->result_ready = 1;
4541 }
4542
4543 static u8 *
4544 format_policer_type (u8 * s, va_list * va)
4545 {
4546   u32 i = va_arg (*va, u32);
4547
4548   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4549     s = format (s, "1r2c");
4550   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4551     s = format (s, "1r3c");
4552   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4553     s = format (s, "2r3c-2698");
4554   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4555     s = format (s, "2r3c-4115");
4556   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4557     s = format (s, "2r3c-mef5cf1");
4558   else
4559     s = format (s, "ILLEGAL");
4560   return s;
4561 }
4562
4563 static u8 *
4564 format_policer_rate_type (u8 * s, va_list * va)
4565 {
4566   u32 i = va_arg (*va, u32);
4567
4568   if (i == SSE2_QOS_RATE_KBPS)
4569     s = format (s, "kbps");
4570   else if (i == SSE2_QOS_RATE_PPS)
4571     s = format (s, "pps");
4572   else
4573     s = format (s, "ILLEGAL");
4574   return s;
4575 }
4576
4577 static u8 *
4578 format_policer_round_type (u8 * s, va_list * va)
4579 {
4580   u32 i = va_arg (*va, u32);
4581
4582   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4583     s = format (s, "closest");
4584   else if (i == SSE2_QOS_ROUND_TO_UP)
4585     s = format (s, "up");
4586   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4587     s = format (s, "down");
4588   else
4589     s = format (s, "ILLEGAL");
4590   return s;
4591 }
4592
4593 static u8 *
4594 format_policer_action_type (u8 * s, va_list * va)
4595 {
4596   u32 i = va_arg (*va, u32);
4597
4598   if (i == SSE2_QOS_ACTION_DROP)
4599     s = format (s, "drop");
4600   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4601     s = format (s, "transmit");
4602   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4603     s = format (s, "mark-and-transmit");
4604   else
4605     s = format (s, "ILLEGAL");
4606   return s;
4607 }
4608
4609 static u8 *
4610 format_dscp (u8 * s, va_list * va)
4611 {
4612   u32 i = va_arg (*va, u32);
4613   char *t = 0;
4614
4615   switch (i)
4616     {
4617 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4618       foreach_vnet_dscp
4619 #undef _
4620     default:
4621       return format (s, "ILLEGAL");
4622     }
4623   s = format (s, "%s", t);
4624   return s;
4625 }
4626
4627 static void
4628 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4629 {
4630   vat_main_t *vam = &vat_main;
4631   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4632
4633   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4634     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4635   else
4636     conform_dscp_str = format (0, "");
4637
4638   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4639     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4640   else
4641     exceed_dscp_str = format (0, "");
4642
4643   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4644     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4645   else
4646     violate_dscp_str = format (0, "");
4647
4648   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4649          "rate type %U, round type %U, %s rate, %s color-aware, "
4650          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4651          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4652          "conform action %U%s, exceed action %U%s, violate action %U%s",
4653          mp->name,
4654          format_policer_type, mp->type,
4655          ntohl (mp->cir),
4656          ntohl (mp->eir),
4657          clib_net_to_host_u64 (mp->cb),
4658          clib_net_to_host_u64 (mp->eb),
4659          format_policer_rate_type, mp->rate_type,
4660          format_policer_round_type, mp->round_type,
4661          mp->single_rate ? "single" : "dual",
4662          mp->color_aware ? "is" : "not",
4663          ntohl (mp->cir_tokens_per_period),
4664          ntohl (mp->pir_tokens_per_period),
4665          ntohl (mp->scale),
4666          ntohl (mp->current_limit),
4667          ntohl (mp->current_bucket),
4668          ntohl (mp->extended_limit),
4669          ntohl (mp->extended_bucket),
4670          clib_net_to_host_u64 (mp->last_update_time),
4671          format_policer_action_type, mp->conform_action_type,
4672          conform_dscp_str,
4673          format_policer_action_type, mp->exceed_action_type,
4674          exceed_dscp_str,
4675          format_policer_action_type, mp->violate_action_type,
4676          violate_dscp_str);
4677
4678   vec_free (conform_dscp_str);
4679   vec_free (exceed_dscp_str);
4680   vec_free (violate_dscp_str);
4681 }
4682
4683 static void vl_api_policer_details_t_handler_json
4684   (vl_api_policer_details_t * mp)
4685 {
4686   vat_main_t *vam = &vat_main;
4687   vat_json_node_t *node;
4688   u8 *rate_type_str, *round_type_str, *type_str;
4689   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4690
4691   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4692   round_type_str =
4693     format (0, "%U", format_policer_round_type, mp->round_type);
4694   type_str = format (0, "%U", format_policer_type, mp->type);
4695   conform_action_str = format (0, "%U", format_policer_action_type,
4696                                mp->conform_action_type);
4697   exceed_action_str = format (0, "%U", format_policer_action_type,
4698                               mp->exceed_action_type);
4699   violate_action_str = format (0, "%U", format_policer_action_type,
4700                                mp->violate_action_type);
4701
4702   if (VAT_JSON_ARRAY != vam->json_tree.type)
4703     {
4704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4705       vat_json_init_array (&vam->json_tree);
4706     }
4707   node = vat_json_array_add (&vam->json_tree);
4708
4709   vat_json_init_object (node);
4710   vat_json_object_add_string_copy (node, "name", mp->name);
4711   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4712   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4713   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4714   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4715   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4716   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4717   vat_json_object_add_string_copy (node, "type", type_str);
4718   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4719   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4720   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4721   vat_json_object_add_uint (node, "cir_tokens_per_period",
4722                             ntohl (mp->cir_tokens_per_period));
4723   vat_json_object_add_uint (node, "eir_tokens_per_period",
4724                             ntohl (mp->pir_tokens_per_period));
4725   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4726   vat_json_object_add_uint (node, "current_bucket",
4727                             ntohl (mp->current_bucket));
4728   vat_json_object_add_uint (node, "extended_limit",
4729                             ntohl (mp->extended_limit));
4730   vat_json_object_add_uint (node, "extended_bucket",
4731                             ntohl (mp->extended_bucket));
4732   vat_json_object_add_uint (node, "last_update_time",
4733                             ntohl (mp->last_update_time));
4734   vat_json_object_add_string_copy (node, "conform_action",
4735                                    conform_action_str);
4736   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4737     {
4738       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4739       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4740       vec_free (dscp_str);
4741     }
4742   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4743   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4744     {
4745       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4746       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4747       vec_free (dscp_str);
4748     }
4749   vat_json_object_add_string_copy (node, "violate_action",
4750                                    violate_action_str);
4751   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4752     {
4753       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4754       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4755       vec_free (dscp_str);
4756     }
4757
4758   vec_free (rate_type_str);
4759   vec_free (round_type_str);
4760   vec_free (type_str);
4761   vec_free (conform_action_str);
4762   vec_free (exceed_action_str);
4763   vec_free (violate_action_str);
4764 }
4765
4766 static void
4767 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4768                                            mp)
4769 {
4770   vat_main_t *vam = &vat_main;
4771   int i, count = ntohl (mp->count);
4772
4773   if (count > 0)
4774     print (vam->ofp, "classify table ids (%d) : ", count);
4775   for (i = 0; i < count; i++)
4776     {
4777       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4778       print (vam->ofp, (i < count - 1) ? "," : "");
4779     }
4780   vam->retval = ntohl (mp->retval);
4781   vam->result_ready = 1;
4782 }
4783
4784 static void
4785   vl_api_classify_table_ids_reply_t_handler_json
4786   (vl_api_classify_table_ids_reply_t * mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   int i, count = ntohl (mp->count);
4790
4791   if (count > 0)
4792     {
4793       vat_json_node_t node;
4794
4795       vat_json_init_object (&node);
4796       for (i = 0; i < count; i++)
4797         {
4798           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4799         }
4800       vat_json_print (vam->ofp, &node);
4801       vat_json_free (&node);
4802     }
4803   vam->retval = ntohl (mp->retval);
4804   vam->result_ready = 1;
4805 }
4806
4807 static void
4808   vl_api_classify_table_by_interface_reply_t_handler
4809   (vl_api_classify_table_by_interface_reply_t * mp)
4810 {
4811   vat_main_t *vam = &vat_main;
4812   u32 table_id;
4813
4814   table_id = ntohl (mp->l2_table_id);
4815   if (table_id != ~0)
4816     print (vam->ofp, "l2 table id : %d", table_id);
4817   else
4818     print (vam->ofp, "l2 table id : No input ACL tables configured");
4819   table_id = ntohl (mp->ip4_table_id);
4820   if (table_id != ~0)
4821     print (vam->ofp, "ip4 table id : %d", table_id);
4822   else
4823     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4824   table_id = ntohl (mp->ip6_table_id);
4825   if (table_id != ~0)
4826     print (vam->ofp, "ip6 table id : %d", table_id);
4827   else
4828     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4829   vam->retval = ntohl (mp->retval);
4830   vam->result_ready = 1;
4831 }
4832
4833 static void
4834   vl_api_classify_table_by_interface_reply_t_handler_json
4835   (vl_api_classify_table_by_interface_reply_t * mp)
4836 {
4837   vat_main_t *vam = &vat_main;
4838   vat_json_node_t node;
4839
4840   vat_json_init_object (&node);
4841
4842   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4843   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4844   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4845
4846   vat_json_print (vam->ofp, &node);
4847   vat_json_free (&node);
4848
4849   vam->retval = ntohl (mp->retval);
4850   vam->result_ready = 1;
4851 }
4852
4853 static void vl_api_policer_add_del_reply_t_handler
4854   (vl_api_policer_add_del_reply_t * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858   if (vam->async_mode)
4859     {
4860       vam->async_errors += (retval < 0);
4861     }
4862   else
4863     {
4864       vam->retval = retval;
4865       vam->result_ready = 1;
4866       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4867         /*
4868          * Note: this is just barely thread-safe, depends on
4869          * the main thread spinning waiting for an answer...
4870          */
4871         errmsg ("policer index %d", ntohl (mp->policer_index));
4872     }
4873 }
4874
4875 static void vl_api_policer_add_del_reply_t_handler_json
4876   (vl_api_policer_add_del_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   vat_json_init_object (&node);
4882   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4883   vat_json_object_add_uint (&node, "policer_index",
4884                             ntohl (mp->policer_index));
4885
4886   vat_json_print (vam->ofp, &node);
4887   vat_json_free (&node);
4888
4889   vam->retval = ntohl (mp->retval);
4890   vam->result_ready = 1;
4891 }
4892
4893 /* Format hex dump. */
4894 u8 *
4895 format_hex_bytes (u8 * s, va_list * va)
4896 {
4897   u8 *bytes = va_arg (*va, u8 *);
4898   int n_bytes = va_arg (*va, int);
4899   uword i;
4900
4901   /* Print short or long form depending on byte count. */
4902   uword short_form = n_bytes <= 32;
4903   u32 indent = format_get_indent (s);
4904
4905   if (n_bytes == 0)
4906     return s;
4907
4908   for (i = 0; i < n_bytes; i++)
4909     {
4910       if (!short_form && (i % 32) == 0)
4911         s = format (s, "%08x: ", i);
4912       s = format (s, "%02x", bytes[i]);
4913       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4914         s = format (s, "\n%U", format_white_space, indent);
4915     }
4916
4917   return s;
4918 }
4919
4920 static void
4921 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4922                                             * mp)
4923 {
4924   vat_main_t *vam = &vat_main;
4925   i32 retval = ntohl (mp->retval);
4926   if (retval == 0)
4927     {
4928       print (vam->ofp, "classify table info :");
4929       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4930              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4931              ntohl (mp->miss_next_index));
4932       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4933              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4934              ntohl (mp->match_n_vectors));
4935       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4936              ntohl (mp->mask_length));
4937     }
4938   vam->retval = retval;
4939   vam->result_ready = 1;
4940 }
4941
4942 static void
4943   vl_api_classify_table_info_reply_t_handler_json
4944   (vl_api_classify_table_info_reply_t * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947   vat_json_node_t node;
4948
4949   i32 retval = ntohl (mp->retval);
4950   if (retval == 0)
4951     {
4952       vat_json_init_object (&node);
4953
4954       vat_json_object_add_int (&node, "sessions",
4955                                ntohl (mp->active_sessions));
4956       vat_json_object_add_int (&node, "nexttbl",
4957                                ntohl (mp->next_table_index));
4958       vat_json_object_add_int (&node, "nextnode",
4959                                ntohl (mp->miss_next_index));
4960       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4961       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4962       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4963       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4964                       ntohl (mp->mask_length), 0);
4965       vat_json_object_add_string_copy (&node, "mask", s);
4966
4967       vat_json_print (vam->ofp, &node);
4968       vat_json_free (&node);
4969     }
4970   vam->retval = ntohl (mp->retval);
4971   vam->result_ready = 1;
4972 }
4973
4974 static void
4975 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4976                                            mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979
4980   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4981          ntohl (mp->hit_next_index), ntohl (mp->advance),
4982          ntohl (mp->opaque_index));
4983   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4984          ntohl (mp->match_length));
4985 }
4986
4987 static void
4988   vl_api_classify_session_details_t_handler_json
4989   (vl_api_classify_session_details_t * mp)
4990 {
4991   vat_main_t *vam = &vat_main;
4992   vat_json_node_t *node = NULL;
4993
4994   if (VAT_JSON_ARRAY != vam->json_tree.type)
4995     {
4996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4997       vat_json_init_array (&vam->json_tree);
4998     }
4999   node = vat_json_array_add (&vam->json_tree);
5000
5001   vat_json_init_object (node);
5002   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5003   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5004   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5005   u8 *s =
5006     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5007             0);
5008   vat_json_object_add_string_copy (node, "match", s);
5009 }
5010
5011 static void vl_api_pg_create_interface_reply_t_handler
5012   (vl_api_pg_create_interface_reply_t * mp)
5013 {
5014   vat_main_t *vam = &vat_main;
5015
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void vl_api_pg_create_interface_reply_t_handler_json
5021   (vl_api_pg_create_interface_reply_t * mp)
5022 {
5023   vat_main_t *vam = &vat_main;
5024   vat_json_node_t node;
5025
5026   i32 retval = ntohl (mp->retval);
5027   if (retval == 0)
5028     {
5029       vat_json_init_object (&node);
5030
5031       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5032
5033       vat_json_print (vam->ofp, &node);
5034       vat_json_free (&node);
5035     }
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_classify_details_t_handler
5041   (vl_api_policer_classify_details_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044
5045   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5046          ntohl (mp->table_index));
5047 }
5048
5049 static void vl_api_policer_classify_details_t_handler_json
5050   (vl_api_policer_classify_details_t * mp)
5051 {
5052   vat_main_t *vam = &vat_main;
5053   vat_json_node_t *node;
5054
5055   if (VAT_JSON_ARRAY != vam->json_tree.type)
5056     {
5057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5058       vat_json_init_array (&vam->json_tree);
5059     }
5060   node = vat_json_array_add (&vam->json_tree);
5061
5062   vat_json_init_object (node);
5063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5064   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5065 }
5066
5067 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5068   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5069 {
5070   vat_main_t *vam = &vat_main;
5071   i32 retval = ntohl (mp->retval);
5072   if (vam->async_mode)
5073     {
5074       vam->async_errors += (retval < 0);
5075     }
5076   else
5077     {
5078       vam->retval = retval;
5079       vam->sw_if_index = ntohl (mp->sw_if_index);
5080       vam->result_ready = 1;
5081     }
5082   vam->regenerate_interface_table = 1;
5083 }
5084
5085 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5086   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5087 {
5088   vat_main_t *vam = &vat_main;
5089   vat_json_node_t node;
5090
5091   vat_json_init_object (&node);
5092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5093   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5094
5095   vat_json_print (vam->ofp, &node);
5096   vat_json_free (&node);
5097
5098   vam->retval = ntohl (mp->retval);
5099   vam->result_ready = 1;
5100 }
5101
5102 static void vl_api_flow_classify_details_t_handler
5103   (vl_api_flow_classify_details_t * mp)
5104 {
5105   vat_main_t *vam = &vat_main;
5106
5107   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5108          ntohl (mp->table_index));
5109 }
5110
5111 static void vl_api_flow_classify_details_t_handler_json
5112   (vl_api_flow_classify_details_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t *node;
5116
5117   if (VAT_JSON_ARRAY != vam->json_tree.type)
5118     {
5119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5120       vat_json_init_array (&vam->json_tree);
5121     }
5122   node = vat_json_array_add (&vam->json_tree);
5123
5124   vat_json_init_object (node);
5125   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5126   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5127 }
5128
5129 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5130 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5131 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5132 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5133 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5134 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5135 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5136 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5137 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5138 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5139
5140 /*
5141  * Generate boilerplate reply handlers, which
5142  * dig the return value out of the xxx_reply_t API message,
5143  * stick it into vam->retval, and set vam->result_ready
5144  *
5145  * Could also do this by pointing N message decode slots at
5146  * a single function, but that could break in subtle ways.
5147  */
5148
5149 #define foreach_standard_reply_retval_handler           \
5150 _(sw_interface_set_flags_reply)                         \
5151 _(sw_interface_add_del_address_reply)                   \
5152 _(sw_interface_set_rx_mode_reply)                       \
5153 _(sw_interface_set_rx_placement_reply)                  \
5154 _(sw_interface_set_table_reply)                         \
5155 _(sw_interface_set_mpls_enable_reply)                   \
5156 _(sw_interface_set_vpath_reply)                         \
5157 _(sw_interface_set_vxlan_bypass_reply)                  \
5158 _(sw_interface_set_geneve_bypass_reply)                 \
5159 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5160 _(sw_interface_set_l2_bridge_reply)                     \
5161 _(bridge_domain_add_del_reply)                          \
5162 _(sw_interface_set_l2_xconnect_reply)                   \
5163 _(l2fib_add_del_reply)                                  \
5164 _(l2fib_flush_int_reply)                                \
5165 _(l2fib_flush_bd_reply)                                 \
5166 _(ip_add_del_route_reply)                               \
5167 _(ip_table_add_del_reply)                               \
5168 _(ip_mroute_add_del_reply)                              \
5169 _(mpls_route_add_del_reply)                             \
5170 _(mpls_table_add_del_reply)                             \
5171 _(mpls_ip_bind_unbind_reply)                            \
5172 _(bier_route_add_del_reply)                             \
5173 _(bier_table_add_del_reply)                             \
5174 _(proxy_arp_add_del_reply)                              \
5175 _(proxy_arp_intfc_enable_disable_reply)                 \
5176 _(sw_interface_set_unnumbered_reply)                    \
5177 _(ip_neighbor_add_del_reply)                            \
5178 _(reset_fib_reply)                                      \
5179 _(dhcp_proxy_config_reply)                              \
5180 _(dhcp_proxy_set_vss_reply)                             \
5181 _(dhcp_client_config_reply)                             \
5182 _(set_ip_flow_hash_reply)                               \
5183 _(sw_interface_ip6_enable_disable_reply)                \
5184 _(ip6nd_proxy_add_del_reply)                            \
5185 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5186 _(sw_interface_ip6nd_ra_config_reply)                   \
5187 _(set_arp_neighbor_limit_reply)                         \
5188 _(l2_patch_add_del_reply)                               \
5189 _(sr_mpls_policy_add_reply)                             \
5190 _(sr_mpls_policy_mod_reply)                             \
5191 _(sr_mpls_policy_del_reply)                             \
5192 _(sr_policy_add_reply)                                  \
5193 _(sr_policy_mod_reply)                                  \
5194 _(sr_policy_del_reply)                                  \
5195 _(sr_localsid_add_del_reply)                            \
5196 _(sr_steering_add_del_reply)                            \
5197 _(classify_add_del_session_reply)                       \
5198 _(classify_set_interface_ip_table_reply)                \
5199 _(classify_set_interface_l2_tables_reply)               \
5200 _(l2tpv3_set_tunnel_cookies_reply)                      \
5201 _(l2tpv3_interface_enable_disable_reply)                \
5202 _(l2tpv3_set_lookup_key_reply)                          \
5203 _(l2_fib_clear_table_reply)                             \
5204 _(l2_interface_efp_filter_reply)                        \
5205 _(l2_interface_vlan_tag_rewrite_reply)                  \
5206 _(modify_vhost_user_if_reply)                           \
5207 _(delete_vhost_user_if_reply)                           \
5208 _(ip_probe_neighbor_reply)                              \
5209 _(ip_scan_neighbor_enable_disable_reply)                \
5210 _(want_ip4_arp_events_reply)                            \
5211 _(want_ip6_nd_events_reply)                             \
5212 _(want_l2_macs_events_reply)                            \
5213 _(input_acl_set_interface_reply)                        \
5214 _(ipsec_spd_add_del_reply)                              \
5215 _(ipsec_interface_add_del_spd_reply)                    \
5216 _(ipsec_spd_entry_add_del_reply)                        \
5217 _(ipsec_sad_entry_add_del_reply)                        \
5218 _(ipsec_tunnel_if_add_del_reply)                        \
5219 _(ipsec_tunnel_if_set_sa_reply)                         \
5220 _(delete_loopback_reply)                                \
5221 _(bd_ip_mac_add_del_reply)                              \
5222 _(bd_ip_mac_flush_reply)                                \
5223 _(want_interface_events_reply)                          \
5224 _(cop_interface_enable_disable_reply)                   \
5225 _(cop_whitelist_enable_disable_reply)                   \
5226 _(sw_interface_clear_stats_reply)                       \
5227 _(ioam_enable_reply)                                    \
5228 _(ioam_disable_reply)                                   \
5229 _(one_add_del_locator_reply)                            \
5230 _(one_add_del_local_eid_reply)                          \
5231 _(one_add_del_remote_mapping_reply)                     \
5232 _(one_add_del_adjacency_reply)                          \
5233 _(one_add_del_map_resolver_reply)                       \
5234 _(one_add_del_map_server_reply)                         \
5235 _(one_enable_disable_reply)                             \
5236 _(one_rloc_probe_enable_disable_reply)                  \
5237 _(one_map_register_enable_disable_reply)                \
5238 _(one_map_register_set_ttl_reply)                       \
5239 _(one_set_transport_protocol_reply)                     \
5240 _(one_map_register_fallback_threshold_reply)            \
5241 _(one_pitr_set_locator_set_reply)                       \
5242 _(one_map_request_mode_reply)                           \
5243 _(one_add_del_map_request_itr_rlocs_reply)              \
5244 _(one_eid_table_add_del_map_reply)                      \
5245 _(one_use_petr_reply)                                   \
5246 _(one_stats_enable_disable_reply)                       \
5247 _(one_add_del_l2_arp_entry_reply)                       \
5248 _(one_add_del_ndp_entry_reply)                          \
5249 _(one_stats_flush_reply)                                \
5250 _(one_enable_disable_xtr_mode_reply)                    \
5251 _(one_enable_disable_pitr_mode_reply)                   \
5252 _(one_enable_disable_petr_mode_reply)                   \
5253 _(gpe_enable_disable_reply)                             \
5254 _(gpe_set_encap_mode_reply)                             \
5255 _(gpe_add_del_iface_reply)                              \
5256 _(gpe_add_del_native_fwd_rpath_reply)                   \
5257 _(af_packet_delete_reply)                               \
5258 _(policer_classify_set_interface_reply)                 \
5259 _(netmap_create_reply)                                  \
5260 _(netmap_delete_reply)                                  \
5261 _(set_ipfix_exporter_reply)                             \
5262 _(set_ipfix_classify_stream_reply)                      \
5263 _(ipfix_classify_table_add_del_reply)                   \
5264 _(flow_classify_set_interface_reply)                    \
5265 _(sw_interface_span_enable_disable_reply)               \
5266 _(pg_capture_reply)                                     \
5267 _(pg_enable_disable_reply)                              \
5268 _(ip_source_and_port_range_check_add_del_reply)         \
5269 _(ip_source_and_port_range_check_interface_add_del_reply)\
5270 _(delete_subif_reply)                                   \
5271 _(l2_interface_pbb_tag_rewrite_reply)                   \
5272 _(set_punt_reply)                                       \
5273 _(feature_enable_disable_reply)                         \
5274 _(sw_interface_tag_add_del_reply)                       \
5275 _(hw_interface_set_mtu_reply)                           \
5276 _(p2p_ethernet_add_reply)                               \
5277 _(p2p_ethernet_del_reply)                               \
5278 _(lldp_config_reply)                                    \
5279 _(sw_interface_set_lldp_reply)                          \
5280 _(tcp_configure_src_addresses_reply)                    \
5281 _(dns_enable_disable_reply)                             \
5282 _(dns_name_server_add_del_reply)                        \
5283 _(session_rule_add_del_reply)                           \
5284 _(ip_container_proxy_add_del_reply)                     \
5285 _(output_acl_set_interface_reply)                       \
5286 _(qos_record_enable_disable_reply)
5287
5288 #define _(n)                                    \
5289     static void vl_api_##n##_t_handler          \
5290     (vl_api_##n##_t * mp)                       \
5291     {                                           \
5292         vat_main_t * vam = &vat_main;           \
5293         i32 retval = ntohl(mp->retval);         \
5294         if (vam->async_mode) {                  \
5295             vam->async_errors += (retval < 0);  \
5296         } else {                                \
5297             vam->retval = retval;               \
5298             vam->result_ready = 1;              \
5299         }                                       \
5300     }
5301 foreach_standard_reply_retval_handler;
5302 #undef _
5303
5304 #define _(n)                                    \
5305     static void vl_api_##n##_t_handler_json     \
5306     (vl_api_##n##_t * mp)                       \
5307     {                                           \
5308         vat_main_t * vam = &vat_main;           \
5309         vat_json_node_t node;                   \
5310         vat_json_init_object(&node);            \
5311         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5312         vat_json_print(vam->ofp, &node);        \
5313         vam->retval = ntohl(mp->retval);        \
5314         vam->result_ready = 1;                  \
5315     }
5316 foreach_standard_reply_retval_handler;
5317 #undef _
5318
5319 /*
5320  * Table of message reply handlers, must include boilerplate handlers
5321  * we just generated
5322  */
5323
5324 #define foreach_vpe_api_reply_msg                                       \
5325 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5326 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5327 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5328 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5329 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5330 _(CLI_REPLY, cli_reply)                                                 \
5331 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5332 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5333   sw_interface_add_del_address_reply)                                   \
5334 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5335 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5336 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5337 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5338 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5339 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5340 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5341 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5342 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5343 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5344   sw_interface_set_l2_xconnect_reply)                                   \
5345 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5346   sw_interface_set_l2_bridge_reply)                                     \
5347 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5348 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5349 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5350 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5351 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5352 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5353 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5354 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5355 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5356 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5357 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5358 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5359 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5360 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5361 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5362 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5363 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5364 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5365 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5366 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5367 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5368 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5369 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5370 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5371 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5372 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5373 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5374 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5375 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5376 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5377   proxy_arp_intfc_enable_disable_reply)                                 \
5378 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5379 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5380   sw_interface_set_unnumbered_reply)                                    \
5381 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5382 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5383 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5384 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5385 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5386 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5387 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5388 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5389 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5390 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5391   sw_interface_ip6_enable_disable_reply)                                \
5392 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5393 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5394 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5395   sw_interface_ip6nd_ra_prefix_reply)                                   \
5396 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5397   sw_interface_ip6nd_ra_config_reply)                                   \
5398 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5399 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5400 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5401 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5402 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5403 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5404 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5405 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5406 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5407 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5408 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5409 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5410 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5411 classify_set_interface_ip_table_reply)                                  \
5412 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5413   classify_set_interface_l2_tables_reply)                               \
5414 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5415 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5416 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5417 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5418 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5419   l2tpv3_interface_enable_disable_reply)                                \
5420 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5421 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5422 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5423 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5424 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5425 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5426 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5427 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5428 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5429 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5430 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5431 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5432 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5433 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5434 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5435 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5436 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5437 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5438 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5439 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5440 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5441 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5442 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5443 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5444 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5445 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5446 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5447 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5448 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5449 _(L2_MACS_EVENT, l2_macs_event)                                         \
5450 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5451 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5452 _(IP_DETAILS, ip_details)                                               \
5453 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5454 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5455 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5456 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5457 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5458 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5459 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5460 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5461 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5462 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5463 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5464 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5465 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5466 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5467 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5468 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5469 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5470 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5471 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5472 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5473 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5474 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5475 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5476 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5477 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5478 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5479 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5480 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5481 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5482   one_map_register_enable_disable_reply)                                \
5483 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5484 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5485 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5486 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5487   one_map_register_fallback_threshold_reply)                            \
5488 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5489   one_rloc_probe_enable_disable_reply)                                  \
5490 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5491 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5492 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5493 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5494 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5495 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5496 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5497 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5498 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5499 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5500 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5501 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5502 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5503 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5504 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5505 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5506   show_one_stats_enable_disable_reply)                                  \
5507 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5508 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5509 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5510 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5511 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5512 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5513 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5514 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5515   one_enable_disable_pitr_mode_reply)                                   \
5516 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5517   one_enable_disable_petr_mode_reply)                                   \
5518 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5519 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5520 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5521 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5522 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5523 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5524 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5525 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5526 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5527 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5528 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5529 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5530   gpe_add_del_native_fwd_rpath_reply)                                   \
5531 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5532   gpe_fwd_entry_path_details)                                           \
5533 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5534 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5535   one_add_del_map_request_itr_rlocs_reply)                              \
5536 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5537   one_get_map_request_itr_rlocs_reply)                                  \
5538 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5539 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5540 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5541 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5542 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5543 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5544   show_one_map_register_state_reply)                                    \
5545 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5546 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5547   show_one_map_register_fallback_threshold_reply)                       \
5548 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5549 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5550 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5551 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5552 _(POLICER_DETAILS, policer_details)                                     \
5553 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5554 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5555 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5556 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5557 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5558 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5559 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5560 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5561 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5562 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5563 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5564 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5565 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5566 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5567 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5568 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5569 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5570 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5571 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5572 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5573 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5574 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5575 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5576 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5577 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5578  ip_source_and_port_range_check_add_del_reply)                          \
5579 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5580  ip_source_and_port_range_check_interface_add_del_reply)                \
5581 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5582 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5583 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5584 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5585 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5586 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5587 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5588 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5589 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5590 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5591 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5592 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5593 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5594 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5595 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5596 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5597 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5598 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5599 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5600 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5601 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5602 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5603 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5604 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5605 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5606 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5607 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5608 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5609
5610 #define foreach_standalone_reply_msg                                    \
5611 _(SW_INTERFACE_EVENT, sw_interface_event)
5612
5613 typedef struct
5614 {
5615   u8 *name;
5616   u32 value;
5617 } name_sort_t;
5618
5619 #define STR_VTR_OP_CASE(op)     \
5620     case L2_VTR_ ## op:         \
5621         return "" # op;
5622
5623 static const char *
5624 str_vtr_op (u32 vtr_op)
5625 {
5626   switch (vtr_op)
5627     {
5628       STR_VTR_OP_CASE (DISABLED);
5629       STR_VTR_OP_CASE (PUSH_1);
5630       STR_VTR_OP_CASE (PUSH_2);
5631       STR_VTR_OP_CASE (POP_1);
5632       STR_VTR_OP_CASE (POP_2);
5633       STR_VTR_OP_CASE (TRANSLATE_1_1);
5634       STR_VTR_OP_CASE (TRANSLATE_1_2);
5635       STR_VTR_OP_CASE (TRANSLATE_2_1);
5636       STR_VTR_OP_CASE (TRANSLATE_2_2);
5637     }
5638
5639   return "UNKNOWN";
5640 }
5641
5642 static int
5643 dump_sub_interface_table (vat_main_t * vam)
5644 {
5645   const sw_interface_subif_t *sub = NULL;
5646
5647   if (vam->json_output)
5648     {
5649       clib_warning
5650         ("JSON output supported only for VPE API calls and dump_stats_table");
5651       return -99;
5652     }
5653
5654   print (vam->ofp,
5655          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5656          "Interface", "sw_if_index",
5657          "sub id", "dot1ad", "tags", "outer id",
5658          "inner id", "exact", "default", "outer any", "inner any");
5659
5660   vec_foreach (sub, vam->sw_if_subif_table)
5661   {
5662     print (vam->ofp,
5663            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5664            sub->interface_name,
5665            sub->sw_if_index,
5666            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5667            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5668            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5669            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5670     if (sub->vtr_op != L2_VTR_DISABLED)
5671       {
5672         print (vam->ofp,
5673                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5674                "tag1: %d tag2: %d ]",
5675                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5676                sub->vtr_tag1, sub->vtr_tag2);
5677       }
5678   }
5679
5680   return 0;
5681 }
5682
5683 static int
5684 name_sort_cmp (void *a1, void *a2)
5685 {
5686   name_sort_t *n1 = a1;
5687   name_sort_t *n2 = a2;
5688
5689   return strcmp ((char *) n1->name, (char *) n2->name);
5690 }
5691
5692 static int
5693 dump_interface_table (vat_main_t * vam)
5694 {
5695   hash_pair_t *p;
5696   name_sort_t *nses = 0, *ns;
5697
5698   if (vam->json_output)
5699     {
5700       clib_warning
5701         ("JSON output supported only for VPE API calls and dump_stats_table");
5702       return -99;
5703     }
5704
5705   /* *INDENT-OFF* */
5706   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5707   ({
5708     vec_add2 (nses, ns, 1);
5709     ns->name = (u8 *)(p->key);
5710     ns->value = (u32) p->value[0];
5711   }));
5712   /* *INDENT-ON* */
5713
5714   vec_sort_with_function (nses, name_sort_cmp);
5715
5716   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5717   vec_foreach (ns, nses)
5718   {
5719     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5720   }
5721   vec_free (nses);
5722   return 0;
5723 }
5724
5725 static int
5726 dump_ip_table (vat_main_t * vam, int is_ipv6)
5727 {
5728   const ip_details_t *det = NULL;
5729   const ip_address_details_t *address = NULL;
5730   u32 i = ~0;
5731
5732   print (vam->ofp, "%-12s", "sw_if_index");
5733
5734   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5735   {
5736     i++;
5737     if (!det->present)
5738       {
5739         continue;
5740       }
5741     print (vam->ofp, "%-12d", i);
5742     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5743     if (!det->addr)
5744       {
5745         continue;
5746       }
5747     vec_foreach (address, det->addr)
5748     {
5749       print (vam->ofp,
5750              "            %-30U%-13d",
5751              is_ipv6 ? format_ip6_address : format_ip4_address,
5752              address->ip, address->prefix_length);
5753     }
5754   }
5755
5756   return 0;
5757 }
5758
5759 static int
5760 dump_ipv4_table (vat_main_t * vam)
5761 {
5762   if (vam->json_output)
5763     {
5764       clib_warning
5765         ("JSON output supported only for VPE API calls and dump_stats_table");
5766       return -99;
5767     }
5768
5769   return dump_ip_table (vam, 0);
5770 }
5771
5772 static int
5773 dump_ipv6_table (vat_main_t * vam)
5774 {
5775   if (vam->json_output)
5776     {
5777       clib_warning
5778         ("JSON output supported only for VPE API calls and dump_stats_table");
5779       return -99;
5780     }
5781
5782   return dump_ip_table (vam, 1);
5783 }
5784
5785 /*
5786  * Pass CLI buffers directly in the CLI_INBAND API message,
5787  * instead of an additional shared memory area.
5788  */
5789 static int
5790 exec_inband (vat_main_t * vam)
5791 {
5792   vl_api_cli_inband_t *mp;
5793   unformat_input_t *i = vam->input;
5794   int ret;
5795
5796   if (vec_len (i->buffer) == 0)
5797     return -1;
5798
5799   if (vam->exec_mode == 0 && unformat (i, "mode"))
5800     {
5801       vam->exec_mode = 1;
5802       return 0;
5803     }
5804   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5805     {
5806       vam->exec_mode = 0;
5807       return 0;
5808     }
5809
5810   /*
5811    * In order for the CLI command to work, it
5812    * must be a vector ending in \n, not a C-string ending
5813    * in \n\0.
5814    */
5815   u32 len = vec_len (vam->input->buffer);
5816   M2 (CLI_INBAND, mp, len);
5817   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5818
5819   S (mp);
5820   W (ret);
5821   /* json responses may or may not include a useful reply... */
5822   if (vec_len (vam->cmd_reply))
5823     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5824   return ret;
5825 }
5826
5827 int
5828 exec (vat_main_t * vam)
5829 {
5830   return exec_inband (vam);
5831 }
5832
5833 static int
5834 api_create_loopback (vat_main_t * vam)
5835 {
5836   unformat_input_t *i = vam->input;
5837   vl_api_create_loopback_t *mp;
5838   vl_api_create_loopback_instance_t *mp_lbi;
5839   u8 mac_address[6];
5840   u8 mac_set = 0;
5841   u8 is_specified = 0;
5842   u32 user_instance = 0;
5843   int ret;
5844
5845   clib_memset (mac_address, 0, sizeof (mac_address));
5846
5847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5848     {
5849       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5850         mac_set = 1;
5851       if (unformat (i, "instance %d", &user_instance))
5852         is_specified = 1;
5853       else
5854         break;
5855     }
5856
5857   if (is_specified)
5858     {
5859       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5860       mp_lbi->is_specified = is_specified;
5861       if (is_specified)
5862         mp_lbi->user_instance = htonl (user_instance);
5863       if (mac_set)
5864         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5865       S (mp_lbi);
5866     }
5867   else
5868     {
5869       /* Construct the API message */
5870       M (CREATE_LOOPBACK, mp);
5871       if (mac_set)
5872         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5873       S (mp);
5874     }
5875
5876   W (ret);
5877   return ret;
5878 }
5879
5880 static int
5881 api_delete_loopback (vat_main_t * vam)
5882 {
5883   unformat_input_t *i = vam->input;
5884   vl_api_delete_loopback_t *mp;
5885   u32 sw_if_index = ~0;
5886   int ret;
5887
5888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5889     {
5890       if (unformat (i, "sw_if_index %d", &sw_if_index))
5891         ;
5892       else
5893         break;
5894     }
5895
5896   if (sw_if_index == ~0)
5897     {
5898       errmsg ("missing sw_if_index");
5899       return -99;
5900     }
5901
5902   /* Construct the API message */
5903   M (DELETE_LOOPBACK, mp);
5904   mp->sw_if_index = ntohl (sw_if_index);
5905
5906   S (mp);
5907   W (ret);
5908   return ret;
5909 }
5910
5911 static int
5912 api_want_interface_events (vat_main_t * vam)
5913 {
5914   unformat_input_t *i = vam->input;
5915   vl_api_want_interface_events_t *mp;
5916   int enable = -1;
5917   int ret;
5918
5919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5920     {
5921       if (unformat (i, "enable"))
5922         enable = 1;
5923       else if (unformat (i, "disable"))
5924         enable = 0;
5925       else
5926         break;
5927     }
5928
5929   if (enable == -1)
5930     {
5931       errmsg ("missing enable|disable");
5932       return -99;
5933     }
5934
5935   M (WANT_INTERFACE_EVENTS, mp);
5936   mp->enable_disable = enable;
5937
5938   vam->interface_event_display = enable;
5939
5940   S (mp);
5941   W (ret);
5942   return ret;
5943 }
5944
5945
5946 /* Note: non-static, called once to set up the initial intfc table */
5947 int
5948 api_sw_interface_dump (vat_main_t * vam)
5949 {
5950   vl_api_sw_interface_dump_t *mp;
5951   vl_api_control_ping_t *mp_ping;
5952   hash_pair_t *p;
5953   name_sort_t *nses = 0, *ns;
5954   sw_interface_subif_t *sub = NULL;
5955   int ret;
5956
5957   /* Toss the old name table */
5958   /* *INDENT-OFF* */
5959   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5960   ({
5961     vec_add2 (nses, ns, 1);
5962     ns->name = (u8 *)(p->key);
5963     ns->value = (u32) p->value[0];
5964   }));
5965   /* *INDENT-ON* */
5966
5967   hash_free (vam->sw_if_index_by_interface_name);
5968
5969   vec_foreach (ns, nses) vec_free (ns->name);
5970
5971   vec_free (nses);
5972
5973   vec_foreach (sub, vam->sw_if_subif_table)
5974   {
5975     vec_free (sub->interface_name);
5976   }
5977   vec_free (vam->sw_if_subif_table);
5978
5979   /* recreate the interface name hash table */
5980   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5981
5982   /*
5983    * Ask for all interface names. Otherwise, the epic catalog of
5984    * name filters becomes ridiculously long, and vat ends up needing
5985    * to be taught about new interface types.
5986    */
5987   M (SW_INTERFACE_DUMP, mp);
5988   S (mp);
5989
5990   /* Use a control ping for synchronization */
5991   MPING (CONTROL_PING, mp_ping);
5992   S (mp_ping);
5993
5994   W (ret);
5995   return ret;
5996 }
5997
5998 static int
5999 api_sw_interface_set_flags (vat_main_t * vam)
6000 {
6001   unformat_input_t *i = vam->input;
6002   vl_api_sw_interface_set_flags_t *mp;
6003   u32 sw_if_index;
6004   u8 sw_if_index_set = 0;
6005   u8 admin_up = 0;
6006   int ret;
6007
6008   /* Parse args required to build the message */
6009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6010     {
6011       if (unformat (i, "admin-up"))
6012         admin_up = 1;
6013       else if (unformat (i, "admin-down"))
6014         admin_up = 0;
6015       else
6016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6019         sw_if_index_set = 1;
6020       else
6021         break;
6022     }
6023
6024   if (sw_if_index_set == 0)
6025     {
6026       errmsg ("missing interface name or sw_if_index");
6027       return -99;
6028     }
6029
6030   /* Construct the API message */
6031   M (SW_INTERFACE_SET_FLAGS, mp);
6032   mp->sw_if_index = ntohl (sw_if_index);
6033   mp->admin_up_down = admin_up;
6034
6035   /* send it... */
6036   S (mp);
6037
6038   /* Wait for a reply, return the good/bad news... */
6039   W (ret);
6040   return ret;
6041 }
6042
6043 static int
6044 api_sw_interface_set_rx_mode (vat_main_t * vam)
6045 {
6046   unformat_input_t *i = vam->input;
6047   vl_api_sw_interface_set_rx_mode_t *mp;
6048   u32 sw_if_index;
6049   u8 sw_if_index_set = 0;
6050   int ret;
6051   u8 queue_id_valid = 0;
6052   u32 queue_id;
6053   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6054
6055   /* Parse args required to build the message */
6056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6057     {
6058       if (unformat (i, "queue %d", &queue_id))
6059         queue_id_valid = 1;
6060       else if (unformat (i, "polling"))
6061         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6062       else if (unformat (i, "interrupt"))
6063         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6064       else if (unformat (i, "adaptive"))
6065         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6066       else
6067         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6068         sw_if_index_set = 1;
6069       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6070         sw_if_index_set = 1;
6071       else
6072         break;
6073     }
6074
6075   if (sw_if_index_set == 0)
6076     {
6077       errmsg ("missing interface name or sw_if_index");
6078       return -99;
6079     }
6080   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6081     {
6082       errmsg ("missing rx-mode");
6083       return -99;
6084     }
6085
6086   /* Construct the API message */
6087   M (SW_INTERFACE_SET_RX_MODE, mp);
6088   mp->sw_if_index = ntohl (sw_if_index);
6089   mp->mode = mode;
6090   mp->queue_id_valid = queue_id_valid;
6091   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6092
6093   /* send it... */
6094   S (mp);
6095
6096   /* Wait for a reply, return the good/bad news... */
6097   W (ret);
6098   return ret;
6099 }
6100
6101 static int
6102 api_sw_interface_set_rx_placement (vat_main_t * vam)
6103 {
6104   unformat_input_t *i = vam->input;
6105   vl_api_sw_interface_set_rx_placement_t *mp;
6106   u32 sw_if_index;
6107   u8 sw_if_index_set = 0;
6108   int ret;
6109   u8 is_main = 0;
6110   u32 queue_id, thread_index;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "queue %d", &queue_id))
6116         ;
6117       else if (unformat (i, "main"))
6118         is_main = 1;
6119       else if (unformat (i, "worker %d", &thread_index))
6120         ;
6121       else
6122         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6123         sw_if_index_set = 1;
6124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         sw_if_index_set = 1;
6126       else
6127         break;
6128     }
6129
6130   if (sw_if_index_set == 0)
6131     {
6132       errmsg ("missing interface name or sw_if_index");
6133       return -99;
6134     }
6135
6136   if (is_main)
6137     thread_index = 0;
6138   /* Construct the API message */
6139   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6140   mp->sw_if_index = ntohl (sw_if_index);
6141   mp->worker_id = ntohl (thread_index);
6142   mp->queue_id = ntohl (queue_id);
6143   mp->is_main = is_main;
6144
6145   /* send it... */
6146   S (mp);
6147   /* Wait for a reply, return the good/bad news... */
6148   W (ret);
6149   return ret;
6150 }
6151
6152 static void vl_api_sw_interface_rx_placement_details_t_handler
6153   (vl_api_sw_interface_rx_placement_details_t * mp)
6154 {
6155   vat_main_t *vam = &vat_main;
6156   u32 worker_id = ntohl (mp->worker_id);
6157
6158   print (vam->ofp,
6159          "\n%-11d %-11s %-6d %-5d %-9s",
6160          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6161          worker_id, ntohl (mp->queue_id),
6162          (mp->mode ==
6163           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6164 }
6165
6166 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6167   (vl_api_sw_interface_rx_placement_details_t * mp)
6168 {
6169   vat_main_t *vam = &vat_main;
6170   vat_json_node_t *node = NULL;
6171
6172   if (VAT_JSON_ARRAY != vam->json_tree.type)
6173     {
6174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6175       vat_json_init_array (&vam->json_tree);
6176     }
6177   node = vat_json_array_add (&vam->json_tree);
6178
6179   vat_json_init_object (node);
6180   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6181   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6182   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6183   vat_json_object_add_uint (node, "mode", mp->mode);
6184 }
6185
6186 static int
6187 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6188 {
6189   unformat_input_t *i = vam->input;
6190   vl_api_sw_interface_rx_placement_dump_t *mp;
6191   vl_api_control_ping_t *mp_ping;
6192   int ret;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195
6196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6197     {
6198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6199         sw_if_index_set++;
6200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6201         sw_if_index_set++;
6202       else
6203         break;
6204     }
6205
6206   print (vam->ofp,
6207          "\n%-11s %-11s %-6s %-5s %-4s",
6208          "sw_if_index", "main/worker", "thread", "queue", "mode");
6209
6210   /* Dump Interface rx placement */
6211   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6212
6213   if (sw_if_index_set)
6214     mp->sw_if_index = htonl (sw_if_index);
6215   else
6216     mp->sw_if_index = ~0;
6217
6218   S (mp);
6219
6220   /* Use a control ping for synchronization */
6221   MPING (CONTROL_PING, mp_ping);
6222   S (mp_ping);
6223
6224   W (ret);
6225   return ret;
6226 }
6227
6228 static int
6229 api_sw_interface_clear_stats (vat_main_t * vam)
6230 {
6231   unformat_input_t *i = vam->input;
6232   vl_api_sw_interface_clear_stats_t *mp;
6233   u32 sw_if_index;
6234   u8 sw_if_index_set = 0;
6235   int ret;
6236
6237   /* Parse args required to build the message */
6238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6239     {
6240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6241         sw_if_index_set = 1;
6242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6243         sw_if_index_set = 1;
6244       else
6245         break;
6246     }
6247
6248   /* Construct the API message */
6249   M (SW_INTERFACE_CLEAR_STATS, mp);
6250
6251   if (sw_if_index_set == 1)
6252     mp->sw_if_index = ntohl (sw_if_index);
6253   else
6254     mp->sw_if_index = ~0;
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply, return the good/bad news... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static int
6265 api_sw_interface_add_del_address (vat_main_t * vam)
6266 {
6267   unformat_input_t *i = vam->input;
6268   vl_api_sw_interface_add_del_address_t *mp;
6269   u32 sw_if_index;
6270   u8 sw_if_index_set = 0;
6271   u8 is_add = 1, del_all = 0;
6272   u32 address_length = 0;
6273   u8 v4_address_set = 0;
6274   u8 v6_address_set = 0;
6275   ip4_address_t v4address;
6276   ip6_address_t v6address;
6277   int ret;
6278
6279   /* Parse args required to build the message */
6280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6281     {
6282       if (unformat (i, "del-all"))
6283         del_all = 1;
6284       else if (unformat (i, "del"))
6285         is_add = 0;
6286       else
6287         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6288         sw_if_index_set = 1;
6289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6290         sw_if_index_set = 1;
6291       else if (unformat (i, "%U/%d",
6292                          unformat_ip4_address, &v4address, &address_length))
6293         v4_address_set = 1;
6294       else if (unformat (i, "%U/%d",
6295                          unformat_ip6_address, &v6address, &address_length))
6296         v6_address_set = 1;
6297       else
6298         break;
6299     }
6300
6301   if (sw_if_index_set == 0)
6302     {
6303       errmsg ("missing interface name or sw_if_index");
6304       return -99;
6305     }
6306   if (v4_address_set && v6_address_set)
6307     {
6308       errmsg ("both v4 and v6 addresses set");
6309       return -99;
6310     }
6311   if (!v4_address_set && !v6_address_set && !del_all)
6312     {
6313       errmsg ("no addresses set");
6314       return -99;
6315     }
6316
6317   /* Construct the API message */
6318   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6319
6320   mp->sw_if_index = ntohl (sw_if_index);
6321   mp->is_add = is_add;
6322   mp->del_all = del_all;
6323   if (v6_address_set)
6324     {
6325       mp->is_ipv6 = 1;
6326       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6327     }
6328   else
6329     {
6330       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6331     }
6332   mp->address_length = address_length;
6333
6334   /* send it... */
6335   S (mp);
6336
6337   /* Wait for a reply, return good/bad news  */
6338   W (ret);
6339   return ret;
6340 }
6341
6342 static int
6343 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6344 {
6345   unformat_input_t *i = vam->input;
6346   vl_api_sw_interface_set_mpls_enable_t *mp;
6347   u32 sw_if_index;
6348   u8 sw_if_index_set = 0;
6349   u8 enable = 1;
6350   int ret;
6351
6352   /* Parse args required to build the message */
6353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6354     {
6355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6356         sw_if_index_set = 1;
6357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6358         sw_if_index_set = 1;
6359       else if (unformat (i, "disable"))
6360         enable = 0;
6361       else if (unformat (i, "dis"))
6362         enable = 0;
6363       else
6364         break;
6365     }
6366
6367   if (sw_if_index_set == 0)
6368     {
6369       errmsg ("missing interface name or sw_if_index");
6370       return -99;
6371     }
6372
6373   /* Construct the API message */
6374   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6375
6376   mp->sw_if_index = ntohl (sw_if_index);
6377   mp->enable = enable;
6378
6379   /* send it... */
6380   S (mp);
6381
6382   /* Wait for a reply... */
6383   W (ret);
6384   return ret;
6385 }
6386
6387 static int
6388 api_sw_interface_set_table (vat_main_t * vam)
6389 {
6390   unformat_input_t *i = vam->input;
6391   vl_api_sw_interface_set_table_t *mp;
6392   u32 sw_if_index, vrf_id = 0;
6393   u8 sw_if_index_set = 0;
6394   u8 is_ipv6 = 0;
6395   int ret;
6396
6397   /* Parse args required to build the message */
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "vrf %d", &vrf_id))
6405         ;
6406       else if (unformat (i, "ipv6"))
6407         is_ipv6 = 1;
6408       else
6409         break;
6410     }
6411
6412   if (sw_if_index_set == 0)
6413     {
6414       errmsg ("missing interface name or sw_if_index");
6415       return -99;
6416     }
6417
6418   /* Construct the API message */
6419   M (SW_INTERFACE_SET_TABLE, mp);
6420
6421   mp->sw_if_index = ntohl (sw_if_index);
6422   mp->is_ipv6 = is_ipv6;
6423   mp->vrf_id = ntohl (vrf_id);
6424
6425   /* send it... */
6426   S (mp);
6427
6428   /* Wait for a reply... */
6429   W (ret);
6430   return ret;
6431 }
6432
6433 static void vl_api_sw_interface_get_table_reply_t_handler
6434   (vl_api_sw_interface_get_table_reply_t * mp)
6435 {
6436   vat_main_t *vam = &vat_main;
6437
6438   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6439
6440   vam->retval = ntohl (mp->retval);
6441   vam->result_ready = 1;
6442
6443 }
6444
6445 static void vl_api_sw_interface_get_table_reply_t_handler_json
6446   (vl_api_sw_interface_get_table_reply_t * mp)
6447 {
6448   vat_main_t *vam = &vat_main;
6449   vat_json_node_t node;
6450
6451   vat_json_init_object (&node);
6452   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6453   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6454
6455   vat_json_print (vam->ofp, &node);
6456   vat_json_free (&node);
6457
6458   vam->retval = ntohl (mp->retval);
6459   vam->result_ready = 1;
6460 }
6461
6462 static int
6463 api_sw_interface_get_table (vat_main_t * vam)
6464 {
6465   unformat_input_t *i = vam->input;
6466   vl_api_sw_interface_get_table_t *mp;
6467   u32 sw_if_index;
6468   u8 sw_if_index_set = 0;
6469   u8 is_ipv6 = 0;
6470   int ret;
6471
6472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6473     {
6474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6475         sw_if_index_set = 1;
6476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6477         sw_if_index_set = 1;
6478       else if (unformat (i, "ipv6"))
6479         is_ipv6 = 1;
6480       else
6481         break;
6482     }
6483
6484   if (sw_if_index_set == 0)
6485     {
6486       errmsg ("missing interface name or sw_if_index");
6487       return -99;
6488     }
6489
6490   M (SW_INTERFACE_GET_TABLE, mp);
6491   mp->sw_if_index = htonl (sw_if_index);
6492   mp->is_ipv6 = is_ipv6;
6493
6494   S (mp);
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_set_vpath (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_set_vpath_t *mp;
6504   u32 sw_if_index = 0;
6505   u8 sw_if_index_set = 0;
6506   u8 is_enable = 0;
6507   int ret;
6508
6509   /* Parse args required to build the message */
6510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6511     {
6512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6513         sw_if_index_set = 1;
6514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6515         sw_if_index_set = 1;
6516       else if (unformat (i, "enable"))
6517         is_enable = 1;
6518       else if (unformat (i, "disable"))
6519         is_enable = 0;
6520       else
6521         break;
6522     }
6523
6524   if (sw_if_index_set == 0)
6525     {
6526       errmsg ("missing interface name or sw_if_index");
6527       return -99;
6528     }
6529
6530   /* Construct the API message */
6531   M (SW_INTERFACE_SET_VPATH, mp);
6532
6533   mp->sw_if_index = ntohl (sw_if_index);
6534   mp->enable = is_enable;
6535
6536   /* send it... */
6537   S (mp);
6538
6539   /* Wait for a reply... */
6540   W (ret);
6541   return ret;
6542 }
6543
6544 static int
6545 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6546 {
6547   unformat_input_t *i = vam->input;
6548   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6549   u32 sw_if_index = 0;
6550   u8 sw_if_index_set = 0;
6551   u8 is_enable = 1;
6552   u8 is_ipv6 = 0;
6553   int ret;
6554
6555   /* Parse args required to build the message */
6556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6557     {
6558       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "enable"))
6563         is_enable = 1;
6564       else if (unformat (i, "disable"))
6565         is_enable = 0;
6566       else if (unformat (i, "ip4"))
6567         is_ipv6 = 0;
6568       else if (unformat (i, "ip6"))
6569         is_ipv6 = 1;
6570       else
6571         break;
6572     }
6573
6574   if (sw_if_index_set == 0)
6575     {
6576       errmsg ("missing interface name or sw_if_index");
6577       return -99;
6578     }
6579
6580   /* Construct the API message */
6581   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6582
6583   mp->sw_if_index = ntohl (sw_if_index);
6584   mp->enable = is_enable;
6585   mp->is_ipv6 = is_ipv6;
6586
6587   /* send it... */
6588   S (mp);
6589
6590   /* Wait for a reply... */
6591   W (ret);
6592   return ret;
6593 }
6594
6595 static int
6596 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6597 {
6598   unformat_input_t *i = vam->input;
6599   vl_api_sw_interface_set_geneve_bypass_t *mp;
6600   u32 sw_if_index = 0;
6601   u8 sw_if_index_set = 0;
6602   u8 is_enable = 1;
6603   u8 is_ipv6 = 0;
6604   int ret;
6605
6606   /* Parse args required to build the message */
6607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6608     {
6609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6610         sw_if_index_set = 1;
6611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6612         sw_if_index_set = 1;
6613       else if (unformat (i, "enable"))
6614         is_enable = 1;
6615       else if (unformat (i, "disable"))
6616         is_enable = 0;
6617       else if (unformat (i, "ip4"))
6618         is_ipv6 = 0;
6619       else if (unformat (i, "ip6"))
6620         is_ipv6 = 1;
6621       else
6622         break;
6623     }
6624
6625   if (sw_if_index_set == 0)
6626     {
6627       errmsg ("missing interface name or sw_if_index");
6628       return -99;
6629     }
6630
6631   /* Construct the API message */
6632   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6633
6634   mp->sw_if_index = ntohl (sw_if_index);
6635   mp->enable = is_enable;
6636   mp->is_ipv6 = is_ipv6;
6637
6638   /* send it... */
6639   S (mp);
6640
6641   /* Wait for a reply... */
6642   W (ret);
6643   return ret;
6644 }
6645
6646 static int
6647 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6648 {
6649   unformat_input_t *i = vam->input;
6650   vl_api_sw_interface_set_l2_xconnect_t *mp;
6651   u32 rx_sw_if_index;
6652   u8 rx_sw_if_index_set = 0;
6653   u32 tx_sw_if_index;
6654   u8 tx_sw_if_index_set = 0;
6655   u8 enable = 1;
6656   int ret;
6657
6658   /* Parse args required to build the message */
6659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6660     {
6661       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6662         rx_sw_if_index_set = 1;
6663       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6664         tx_sw_if_index_set = 1;
6665       else if (unformat (i, "rx"))
6666         {
6667           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6668             {
6669               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6670                             &rx_sw_if_index))
6671                 rx_sw_if_index_set = 1;
6672             }
6673           else
6674             break;
6675         }
6676       else if (unformat (i, "tx"))
6677         {
6678           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6679             {
6680               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6681                             &tx_sw_if_index))
6682                 tx_sw_if_index_set = 1;
6683             }
6684           else
6685             break;
6686         }
6687       else if (unformat (i, "enable"))
6688         enable = 1;
6689       else if (unformat (i, "disable"))
6690         enable = 0;
6691       else
6692         break;
6693     }
6694
6695   if (rx_sw_if_index_set == 0)
6696     {
6697       errmsg ("missing rx interface name or rx_sw_if_index");
6698       return -99;
6699     }
6700
6701   if (enable && (tx_sw_if_index_set == 0))
6702     {
6703       errmsg ("missing tx interface name or tx_sw_if_index");
6704       return -99;
6705     }
6706
6707   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6708
6709   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6710   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6711   mp->enable = enable;
6712
6713   S (mp);
6714   W (ret);
6715   return ret;
6716 }
6717
6718 static int
6719 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6720 {
6721   unformat_input_t *i = vam->input;
6722   vl_api_sw_interface_set_l2_bridge_t *mp;
6723   vl_api_l2_port_type_t port_type;
6724   u32 rx_sw_if_index;
6725   u8 rx_sw_if_index_set = 0;
6726   u32 bd_id;
6727   u8 bd_id_set = 0;
6728   u32 shg = 0;
6729   u8 enable = 1;
6730   int ret;
6731
6732   port_type = L2_API_PORT_TYPE_NORMAL;
6733
6734   /* Parse args required to build the message */
6735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736     {
6737       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6738         rx_sw_if_index_set = 1;
6739       else if (unformat (i, "bd_id %d", &bd_id))
6740         bd_id_set = 1;
6741       else
6742         if (unformat
6743             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6744         rx_sw_if_index_set = 1;
6745       else if (unformat (i, "shg %d", &shg))
6746         ;
6747       else if (unformat (i, "bvi"))
6748         port_type = L2_API_PORT_TYPE_BVI;
6749       else if (unformat (i, "uu-fwd"))
6750         port_type = L2_API_PORT_TYPE_UU_FWD;
6751       else if (unformat (i, "enable"))
6752         enable = 1;
6753       else if (unformat (i, "disable"))
6754         enable = 0;
6755       else
6756         break;
6757     }
6758
6759   if (rx_sw_if_index_set == 0)
6760     {
6761       errmsg ("missing rx interface name or sw_if_index");
6762       return -99;
6763     }
6764
6765   if (enable && (bd_id_set == 0))
6766     {
6767       errmsg ("missing bridge domain");
6768       return -99;
6769     }
6770
6771   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6772
6773   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6774   mp->bd_id = ntohl (bd_id);
6775   mp->shg = (u8) shg;
6776   mp->port_type = ntohl (port_type);
6777   mp->enable = enable;
6778
6779   S (mp);
6780   W (ret);
6781   return ret;
6782 }
6783
6784 static int
6785 api_bridge_domain_dump (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_bridge_domain_dump_t *mp;
6789   vl_api_control_ping_t *mp_ping;
6790   u32 bd_id = ~0;
6791   int ret;
6792
6793   /* Parse args required to build the message */
6794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6795     {
6796       if (unformat (i, "bd_id %d", &bd_id))
6797         ;
6798       else
6799         break;
6800     }
6801
6802   M (BRIDGE_DOMAIN_DUMP, mp);
6803   mp->bd_id = ntohl (bd_id);
6804   S (mp);
6805
6806   /* Use a control ping for synchronization */
6807   MPING (CONTROL_PING, mp_ping);
6808   S (mp_ping);
6809
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_bridge_domain_add_del (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_bridge_domain_add_del_t *mp;
6819   u32 bd_id = ~0;
6820   u8 is_add = 1;
6821   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6822   u8 *bd_tag = NULL;
6823   u32 mac_age = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "bd_id %d", &bd_id))
6830         ;
6831       else if (unformat (i, "flood %d", &flood))
6832         ;
6833       else if (unformat (i, "uu-flood %d", &uu_flood))
6834         ;
6835       else if (unformat (i, "forward %d", &forward))
6836         ;
6837       else if (unformat (i, "learn %d", &learn))
6838         ;
6839       else if (unformat (i, "arp-term %d", &arp_term))
6840         ;
6841       else if (unformat (i, "mac-age %d", &mac_age))
6842         ;
6843       else if (unformat (i, "bd-tag %s", &bd_tag))
6844         ;
6845       else if (unformat (i, "del"))
6846         {
6847           is_add = 0;
6848           flood = uu_flood = forward = learn = 0;
6849         }
6850       else
6851         break;
6852     }
6853
6854   if (bd_id == ~0)
6855     {
6856       errmsg ("missing bridge domain");
6857       ret = -99;
6858       goto done;
6859     }
6860
6861   if (mac_age > 255)
6862     {
6863       errmsg ("mac age must be less than 256 ");
6864       ret = -99;
6865       goto done;
6866     }
6867
6868   if ((bd_tag) && (vec_len (bd_tag) > 63))
6869     {
6870       errmsg ("bd-tag cannot be longer than 63");
6871       ret = -99;
6872       goto done;
6873     }
6874
6875   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6876
6877   mp->bd_id = ntohl (bd_id);
6878   mp->flood = flood;
6879   mp->uu_flood = uu_flood;
6880   mp->forward = forward;
6881   mp->learn = learn;
6882   mp->arp_term = arp_term;
6883   mp->is_add = is_add;
6884   mp->mac_age = (u8) mac_age;
6885   if (bd_tag)
6886     {
6887       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6888       mp->bd_tag[vec_len (bd_tag)] = 0;
6889     }
6890   S (mp);
6891   W (ret);
6892
6893 done:
6894   vec_free (bd_tag);
6895   return ret;
6896 }
6897
6898 static int
6899 api_l2fib_flush_bd (vat_main_t * vam)
6900 {
6901   unformat_input_t *i = vam->input;
6902   vl_api_l2fib_flush_bd_t *mp;
6903   u32 bd_id = ~0;
6904   int ret;
6905
6906   /* Parse args required to build the message */
6907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6908     {
6909       if (unformat (i, "bd_id %d", &bd_id));
6910       else
6911         break;
6912     }
6913
6914   if (bd_id == ~0)
6915     {
6916       errmsg ("missing bridge domain");
6917       return -99;
6918     }
6919
6920   M (L2FIB_FLUSH_BD, mp);
6921
6922   mp->bd_id = htonl (bd_id);
6923
6924   S (mp);
6925   W (ret);
6926   return ret;
6927 }
6928
6929 static int
6930 api_l2fib_flush_int (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_l2fib_flush_int_t *mp;
6934   u32 sw_if_index = ~0;
6935   int ret;
6936
6937   /* Parse args required to build the message */
6938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939     {
6940       if (unformat (i, "sw_if_index %d", &sw_if_index));
6941       else
6942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6943       else
6944         break;
6945     }
6946
6947   if (sw_if_index == ~0)
6948     {
6949       errmsg ("missing interface name or sw_if_index");
6950       return -99;
6951     }
6952
6953   M (L2FIB_FLUSH_INT, mp);
6954
6955   mp->sw_if_index = ntohl (sw_if_index);
6956
6957   S (mp);
6958   W (ret);
6959   return ret;
6960 }
6961
6962 static int
6963 api_l2fib_add_del (vat_main_t * vam)
6964 {
6965   unformat_input_t *i = vam->input;
6966   vl_api_l2fib_add_del_t *mp;
6967   f64 timeout;
6968   u8 mac[6] = { 0 };
6969   u8 mac_set = 0;
6970   u32 bd_id;
6971   u8 bd_id_set = 0;
6972   u32 sw_if_index = 0;
6973   u8 sw_if_index_set = 0;
6974   u8 is_add = 1;
6975   u8 static_mac = 0;
6976   u8 filter_mac = 0;
6977   u8 bvi_mac = 0;
6978   int count = 1;
6979   f64 before = 0;
6980   int j;
6981
6982   /* Parse args required to build the message */
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6986         mac_set = 1;
6987       else if (unformat (i, "bd_id %d", &bd_id))
6988         bd_id_set = 1;
6989       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6990         sw_if_index_set = 1;
6991       else if (unformat (i, "sw_if"))
6992         {
6993           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6994             {
6995               if (unformat
6996                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6997                 sw_if_index_set = 1;
6998             }
6999           else
7000             break;
7001         }
7002       else if (unformat (i, "static"))
7003         static_mac = 1;
7004       else if (unformat (i, "filter"))
7005         {
7006           filter_mac = 1;
7007           static_mac = 1;
7008         }
7009       else if (unformat (i, "bvi"))
7010         {
7011           bvi_mac = 1;
7012           static_mac = 1;
7013         }
7014       else if (unformat (i, "del"))
7015         is_add = 0;
7016       else if (unformat (i, "count %d", &count))
7017         ;
7018       else
7019         break;
7020     }
7021
7022   if (mac_set == 0)
7023     {
7024       errmsg ("missing mac address");
7025       return -99;
7026     }
7027
7028   if (bd_id_set == 0)
7029     {
7030       errmsg ("missing bridge domain");
7031       return -99;
7032     }
7033
7034   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7035     {
7036       errmsg ("missing interface name or sw_if_index");
7037       return -99;
7038     }
7039
7040   if (count > 1)
7041     {
7042       /* Turn on async mode */
7043       vam->async_mode = 1;
7044       vam->async_errors = 0;
7045       before = vat_time_now (vam);
7046     }
7047
7048   for (j = 0; j < count; j++)
7049     {
7050       M (L2FIB_ADD_DEL, mp);
7051
7052       clib_memcpy (mp->mac, mac, 6);
7053       mp->bd_id = ntohl (bd_id);
7054       mp->is_add = is_add;
7055       mp->sw_if_index = ntohl (sw_if_index);
7056
7057       if (is_add)
7058         {
7059           mp->static_mac = static_mac;
7060           mp->filter_mac = filter_mac;
7061           mp->bvi_mac = bvi_mac;
7062         }
7063       increment_mac_address (mac);
7064       /* send it... */
7065       S (mp);
7066     }
7067
7068   if (count > 1)
7069     {
7070       vl_api_control_ping_t *mp_ping;
7071       f64 after;
7072
7073       /* Shut off async mode */
7074       vam->async_mode = 0;
7075
7076       MPING (CONTROL_PING, mp_ping);
7077       S (mp_ping);
7078
7079       timeout = vat_time_now (vam) + 1.0;
7080       while (vat_time_now (vam) < timeout)
7081         if (vam->result_ready == 1)
7082           goto out;
7083       vam->retval = -99;
7084
7085     out:
7086       if (vam->retval == -99)
7087         errmsg ("timeout");
7088
7089       if (vam->async_errors > 0)
7090         {
7091           errmsg ("%d asynchronous errors", vam->async_errors);
7092           vam->retval = -98;
7093         }
7094       vam->async_errors = 0;
7095       after = vat_time_now (vam);
7096
7097       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7098              count, after - before, count / (after - before));
7099     }
7100   else
7101     {
7102       int ret;
7103
7104       /* Wait for a reply... */
7105       W (ret);
7106       return ret;
7107     }
7108   /* Return the good/bad news */
7109   return (vam->retval);
7110 }
7111
7112 static int
7113 api_bridge_domain_set_mac_age (vat_main_t * vam)
7114 {
7115   unformat_input_t *i = vam->input;
7116   vl_api_bridge_domain_set_mac_age_t *mp;
7117   u32 bd_id = ~0;
7118   u32 mac_age = 0;
7119   int ret;
7120
7121   /* Parse args required to build the message */
7122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123     {
7124       if (unformat (i, "bd_id %d", &bd_id));
7125       else if (unformat (i, "mac-age %d", &mac_age));
7126       else
7127         break;
7128     }
7129
7130   if (bd_id == ~0)
7131     {
7132       errmsg ("missing bridge domain");
7133       return -99;
7134     }
7135
7136   if (mac_age > 255)
7137     {
7138       errmsg ("mac age must be less than 256 ");
7139       return -99;
7140     }
7141
7142   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7143
7144   mp->bd_id = htonl (bd_id);
7145   mp->mac_age = (u8) mac_age;
7146
7147   S (mp);
7148   W (ret);
7149   return ret;
7150 }
7151
7152 static int
7153 api_l2_flags (vat_main_t * vam)
7154 {
7155   unformat_input_t *i = vam->input;
7156   vl_api_l2_flags_t *mp;
7157   u32 sw_if_index;
7158   u32 flags = 0;
7159   u8 sw_if_index_set = 0;
7160   u8 is_set = 0;
7161   int ret;
7162
7163   /* Parse args required to build the message */
7164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7165     {
7166       if (unformat (i, "sw_if_index %d", &sw_if_index))
7167         sw_if_index_set = 1;
7168       else if (unformat (i, "sw_if"))
7169         {
7170           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171             {
7172               if (unformat
7173                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7174                 sw_if_index_set = 1;
7175             }
7176           else
7177             break;
7178         }
7179       else if (unformat (i, "learn"))
7180         flags |= L2_LEARN;
7181       else if (unformat (i, "forward"))
7182         flags |= L2_FWD;
7183       else if (unformat (i, "flood"))
7184         flags |= L2_FLOOD;
7185       else if (unformat (i, "uu-flood"))
7186         flags |= L2_UU_FLOOD;
7187       else if (unformat (i, "arp-term"))
7188         flags |= L2_ARP_TERM;
7189       else if (unformat (i, "off"))
7190         is_set = 0;
7191       else if (unformat (i, "disable"))
7192         is_set = 0;
7193       else
7194         break;
7195     }
7196
7197   if (sw_if_index_set == 0)
7198     {
7199       errmsg ("missing interface name or sw_if_index");
7200       return -99;
7201     }
7202
7203   M (L2_FLAGS, mp);
7204
7205   mp->sw_if_index = ntohl (sw_if_index);
7206   mp->feature_bitmap = ntohl (flags);
7207   mp->is_set = is_set;
7208
7209   S (mp);
7210   W (ret);
7211   return ret;
7212 }
7213
7214 static int
7215 api_bridge_flags (vat_main_t * vam)
7216 {
7217   unformat_input_t *i = vam->input;
7218   vl_api_bridge_flags_t *mp;
7219   u32 bd_id;
7220   u8 bd_id_set = 0;
7221   u8 is_set = 1;
7222   bd_flags_t flags = 0;
7223   int ret;
7224
7225   /* Parse args required to build the message */
7226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (i, "bd_id %d", &bd_id))
7229         bd_id_set = 1;
7230       else if (unformat (i, "learn"))
7231         flags |= BRIDGE_API_FLAG_LEARN;
7232       else if (unformat (i, "forward"))
7233         flags |= BRIDGE_API_FLAG_FWD;
7234       else if (unformat (i, "flood"))
7235         flags |= BRIDGE_API_FLAG_FLOOD;
7236       else if (unformat (i, "uu-flood"))
7237         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7238       else if (unformat (i, "arp-term"))
7239         flags |= BRIDGE_API_FLAG_ARP_TERM;
7240       else if (unformat (i, "off"))
7241         is_set = 0;
7242       else if (unformat (i, "disable"))
7243         is_set = 0;
7244       else
7245         break;
7246     }
7247
7248   if (bd_id_set == 0)
7249     {
7250       errmsg ("missing bridge domain");
7251       return -99;
7252     }
7253
7254   M (BRIDGE_FLAGS, mp);
7255
7256   mp->bd_id = ntohl (bd_id);
7257   mp->flags = ntohl (flags);
7258   mp->is_set = is_set;
7259
7260   S (mp);
7261   W (ret);
7262   return ret;
7263 }
7264
7265 static int
7266 api_bd_ip_mac_add_del (vat_main_t * vam)
7267 {
7268   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7269   vl_api_mac_address_t mac = { 0 };
7270   unformat_input_t *i = vam->input;
7271   vl_api_bd_ip_mac_add_del_t *mp;
7272   u32 bd_id;
7273   u8 is_add = 1;
7274   u8 bd_id_set = 0;
7275   u8 ip_set = 0;
7276   u8 mac_set = 0;
7277   int ret;
7278
7279
7280   /* Parse args required to build the message */
7281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7282     {
7283       if (unformat (i, "bd_id %d", &bd_id))
7284         {
7285           bd_id_set++;
7286         }
7287       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7288         {
7289           ip_set++;
7290         }
7291       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7292         {
7293           mac_set++;
7294         }
7295       else if (unformat (i, "del"))
7296         is_add = 0;
7297       else
7298         break;
7299     }
7300
7301   if (bd_id_set == 0)
7302     {
7303       errmsg ("missing bridge domain");
7304       return -99;
7305     }
7306   else if (ip_set == 0)
7307     {
7308       errmsg ("missing IP address");
7309       return -99;
7310     }
7311   else if (mac_set == 0)
7312     {
7313       errmsg ("missing MAC address");
7314       return -99;
7315     }
7316
7317   M (BD_IP_MAC_ADD_DEL, mp);
7318
7319   mp->bd_id = ntohl (bd_id);
7320   mp->is_add = is_add;
7321
7322   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7323   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7324
7325   S (mp);
7326   W (ret);
7327   return ret;
7328 }
7329
7330 static int
7331 api_bd_ip_mac_flush (vat_main_t * vam)
7332 {
7333   unformat_input_t *i = vam->input;
7334   vl_api_bd_ip_mac_flush_t *mp;
7335   u32 bd_id;
7336   u8 bd_id_set = 0;
7337   int ret;
7338
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "bd_id %d", &bd_id))
7342         {
7343           bd_id_set++;
7344         }
7345       else
7346         break;
7347     }
7348
7349   if (bd_id_set == 0)
7350     {
7351       errmsg ("missing bridge domain");
7352       return -99;
7353     }
7354
7355   M (BD_IP_MAC_FLUSH, mp);
7356
7357   mp->bd_id = ntohl (bd_id);
7358
7359   S (mp);
7360   W (ret);
7361   return ret;
7362 }
7363
7364 static void vl_api_bd_ip_mac_details_t_handler
7365   (vl_api_bd_ip_mac_details_t * mp)
7366 {
7367   vat_main_t *vam = &vat_main;
7368   u8 *ip = 0;
7369
7370   if (!mp->is_ipv6)
7371     ip =
7372       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7373   else
7374     ip =
7375       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7376
7377   print (vam->ofp,
7378          "\n%-5d %-7s %-20U %-30s",
7379          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7380          format_ethernet_address, mp->mac_address, ip);
7381
7382   vec_free (ip);
7383 }
7384
7385 static void vl_api_bd_ip_mac_details_t_handler_json
7386   (vl_api_bd_ip_mac_details_t * mp)
7387 {
7388   vat_main_t *vam = &vat_main;
7389   vat_json_node_t *node = NULL;
7390
7391   if (VAT_JSON_ARRAY != vam->json_tree.type)
7392     {
7393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7394       vat_json_init_array (&vam->json_tree);
7395     }
7396   node = vat_json_array_add (&vam->json_tree);
7397
7398   vat_json_init_object (node);
7399   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7400   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7401   vat_json_object_add_string_copy (node, "mac_address",
7402                                    format (0, "%U", format_ethernet_address,
7403                                            &mp->mac_address));
7404   u8 *ip = 0;
7405
7406   if (!mp->is_ipv6)
7407     ip =
7408       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7409   else
7410     ip =
7411       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7412   vat_json_object_add_string_copy (node, "ip_address", ip);
7413   vec_free (ip);
7414 }
7415
7416 static int
7417 api_bd_ip_mac_dump (vat_main_t * vam)
7418 {
7419   unformat_input_t *i = vam->input;
7420   vl_api_bd_ip_mac_dump_t *mp;
7421   vl_api_control_ping_t *mp_ping;
7422   int ret;
7423   u32 bd_id;
7424   u8 bd_id_set = 0;
7425
7426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7427     {
7428       if (unformat (i, "bd_id %d", &bd_id))
7429         {
7430           bd_id_set++;
7431         }
7432       else
7433         break;
7434     }
7435
7436   print (vam->ofp,
7437          "\n%-5s %-7s %-20s %-30s",
7438          "bd_id", "is_ipv6", "mac_address", "ip_address");
7439
7440   /* Dump Bridge Domain Ip to Mac entries */
7441   M (BD_IP_MAC_DUMP, mp);
7442
7443   if (bd_id_set)
7444     mp->bd_id = htonl (bd_id);
7445   else
7446     mp->bd_id = ~0;
7447
7448   S (mp);
7449
7450   /* Use a control ping for synchronization */
7451   MPING (CONTROL_PING, mp_ping);
7452   S (mp_ping);
7453
7454   W (ret);
7455   return ret;
7456 }
7457
7458 static int
7459 api_tap_create_v2 (vat_main_t * vam)
7460 {
7461   unformat_input_t *i = vam->input;
7462   vl_api_tap_create_v2_t *mp;
7463   u8 mac_address[6];
7464   u8 random_mac = 1;
7465   u32 id = ~0;
7466   u8 *host_if_name = 0;
7467   u8 *host_ns = 0;
7468   u8 host_mac_addr[6];
7469   u8 host_mac_addr_set = 0;
7470   u8 *host_bridge = 0;
7471   ip4_address_t host_ip4_addr;
7472   ip4_address_t host_ip4_gw;
7473   u8 host_ip4_gw_set = 0;
7474   u32 host_ip4_prefix_len = 0;
7475   ip6_address_t host_ip6_addr;
7476   ip6_address_t host_ip6_gw;
7477   u8 host_ip6_gw_set = 0;
7478   u32 host_ip6_prefix_len = 0;
7479   int ret;
7480   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7481
7482   clib_memset (mac_address, 0, sizeof (mac_address));
7483
7484   /* Parse args required to build the message */
7485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7486     {
7487       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7488         {
7489           random_mac = 0;
7490         }
7491       else if (unformat (i, "id %u", &id))
7492         ;
7493       else if (unformat (i, "host-if-name %s", &host_if_name))
7494         ;
7495       else if (unformat (i, "host-ns %s", &host_ns))
7496         ;
7497       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7498                          host_mac_addr))
7499         host_mac_addr_set = 1;
7500       else if (unformat (i, "host-bridge %s", &host_bridge))
7501         ;
7502       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7503                          &host_ip4_addr, &host_ip4_prefix_len))
7504         ;
7505       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7506                          &host_ip6_addr, &host_ip6_prefix_len))
7507         ;
7508       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7509                          &host_ip4_gw))
7510         host_ip4_gw_set = 1;
7511       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7512                          &host_ip6_gw))
7513         host_ip6_gw_set = 1;
7514       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7515         ;
7516       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7517         ;
7518       else
7519         break;
7520     }
7521
7522   if (vec_len (host_if_name) > 63)
7523     {
7524       errmsg ("tap name too long. ");
7525       return -99;
7526     }
7527   if (vec_len (host_ns) > 63)
7528     {
7529       errmsg ("host name space too long. ");
7530       return -99;
7531     }
7532   if (vec_len (host_bridge) > 63)
7533     {
7534       errmsg ("host bridge name too long. ");
7535       return -99;
7536     }
7537   if (host_ip4_prefix_len > 32)
7538     {
7539       errmsg ("host ip4 prefix length not valid. ");
7540       return -99;
7541     }
7542   if (host_ip6_prefix_len > 128)
7543     {
7544       errmsg ("host ip6 prefix length not valid. ");
7545       return -99;
7546     }
7547   if (!is_pow2 (rx_ring_sz))
7548     {
7549       errmsg ("rx ring size must be power of 2. ");
7550       return -99;
7551     }
7552   if (rx_ring_sz > 32768)
7553     {
7554       errmsg ("rx ring size must be 32768 or lower. ");
7555       return -99;
7556     }
7557   if (!is_pow2 (tx_ring_sz))
7558     {
7559       errmsg ("tx ring size must be power of 2. ");
7560       return -99;
7561     }
7562   if (tx_ring_sz > 32768)
7563     {
7564       errmsg ("tx ring size must be 32768 or lower. ");
7565       return -99;
7566     }
7567
7568   /* Construct the API message */
7569   M (TAP_CREATE_V2, mp);
7570
7571   mp->use_random_mac = random_mac;
7572
7573   mp->id = ntohl (id);
7574   mp->host_namespace_set = host_ns != 0;
7575   mp->host_bridge_set = host_bridge != 0;
7576   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7577   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7578   mp->rx_ring_sz = ntohs (rx_ring_sz);
7579   mp->tx_ring_sz = ntohs (tx_ring_sz);
7580
7581   if (random_mac == 0)
7582     clib_memcpy (mp->mac_address, mac_address, 6);
7583   if (host_mac_addr_set)
7584     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7585   if (host_if_name)
7586     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7587   if (host_ns)
7588     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7589   if (host_bridge)
7590     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7591   if (host_ip4_prefix_len)
7592     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7593   if (host_ip6_prefix_len)
7594     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7595   if (host_ip4_gw_set)
7596     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7597   if (host_ip6_gw_set)
7598     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7599
7600   vec_free (host_ns);
7601   vec_free (host_if_name);
7602   vec_free (host_bridge);
7603
7604   /* send it... */
7605   S (mp);
7606
7607   /* Wait for a reply... */
7608   W (ret);
7609   return ret;
7610 }
7611
7612 static int
7613 api_tap_delete_v2 (vat_main_t * vam)
7614 {
7615   unformat_input_t *i = vam->input;
7616   vl_api_tap_delete_v2_t *mp;
7617   u32 sw_if_index = ~0;
7618   u8 sw_if_index_set = 0;
7619   int ret;
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7625         sw_if_index_set = 1;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         sw_if_index_set = 1;
7628       else
7629         break;
7630     }
7631
7632   if (sw_if_index_set == 0)
7633     {
7634       errmsg ("missing vpp interface name. ");
7635       return -99;
7636     }
7637
7638   /* Construct the API message */
7639   M (TAP_DELETE_V2, mp);
7640
7641   mp->sw_if_index = ntohl (sw_if_index);
7642
7643   /* send it... */
7644   S (mp);
7645
7646   /* Wait for a reply... */
7647   W (ret);
7648   return ret;
7649 }
7650
7651 uword
7652 unformat_pci_addr (unformat_input_t * input, va_list * args)
7653 {
7654   struct pci_addr_t
7655   {
7656     u16 domain;
7657     u8 bus;
7658     u8 slot:5;
7659     u8 function:3;
7660   } *addr;
7661   addr = va_arg (*args, struct pci_addr_t *);
7662   u32 x[4];
7663
7664   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7665     return 0;
7666
7667   addr->domain = x[0];
7668   addr->bus = x[1];
7669   addr->slot = x[2];
7670   addr->function = x[3];
7671
7672   return 1;
7673 }
7674
7675 static int
7676 api_virtio_pci_create (vat_main_t * vam)
7677 {
7678   unformat_input_t *i = vam->input;
7679   vl_api_virtio_pci_create_t *mp;
7680   u8 mac_address[6];
7681   u8 random_mac = 1;
7682   u8 gso_enabled = 0;
7683   u32 pci_addr = 0;
7684   u64 features = (u64) ~ (0ULL);
7685   int ret;
7686
7687   clib_memset (mac_address, 0, sizeof (mac_address));
7688
7689   /* Parse args required to build the message */
7690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7691     {
7692       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7693         {
7694           random_mac = 0;
7695         }
7696       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7697         ;
7698       else if (unformat (i, "features 0x%llx", &features))
7699         ;
7700       else if (unformat (i, "gso-enabled"))
7701         gso_enabled = 1;
7702       else
7703         break;
7704     }
7705
7706   if (pci_addr == 0)
7707     {
7708       errmsg ("pci address must be non zero. ");
7709       return -99;
7710     }
7711
7712   /* Construct the API message */
7713   M (VIRTIO_PCI_CREATE, mp);
7714
7715   mp->use_random_mac = random_mac;
7716
7717   mp->pci_addr = htonl (pci_addr);
7718   mp->features = clib_host_to_net_u64 (features);
7719   mp->gso_enabled = gso_enabled;
7720
7721   if (random_mac == 0)
7722     clib_memcpy (mp->mac_address, mac_address, 6);
7723
7724   /* send it... */
7725   S (mp);
7726
7727   /* Wait for a reply... */
7728   W (ret);
7729   return ret;
7730 }
7731
7732 static int
7733 api_virtio_pci_delete (vat_main_t * vam)
7734 {
7735   unformat_input_t *i = vam->input;
7736   vl_api_virtio_pci_delete_t *mp;
7737   u32 sw_if_index = ~0;
7738   u8 sw_if_index_set = 0;
7739   int ret;
7740
7741   /* Parse args required to build the message */
7742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7743     {
7744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7745         sw_if_index_set = 1;
7746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7747         sw_if_index_set = 1;
7748       else
7749         break;
7750     }
7751
7752   if (sw_if_index_set == 0)
7753     {
7754       errmsg ("missing vpp interface name. ");
7755       return -99;
7756     }
7757
7758   /* Construct the API message */
7759   M (VIRTIO_PCI_DELETE, mp);
7760
7761   mp->sw_if_index = htonl (sw_if_index);
7762
7763   /* send it... */
7764   S (mp);
7765
7766   /* Wait for a reply... */
7767   W (ret);
7768   return ret;
7769 }
7770
7771 static int
7772 api_bond_create (vat_main_t * vam)
7773 {
7774   unformat_input_t *i = vam->input;
7775   vl_api_bond_create_t *mp;
7776   u8 mac_address[6];
7777   u8 custom_mac = 0;
7778   int ret;
7779   u8 mode;
7780   u8 lb;
7781   u8 mode_is_set = 0;
7782   u32 id = ~0;
7783
7784   clib_memset (mac_address, 0, sizeof (mac_address));
7785   lb = BOND_LB_L2;
7786
7787   /* Parse args required to build the message */
7788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7789     {
7790       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7791         mode_is_set = 1;
7792       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7793                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7794         ;
7795       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7796                          mac_address))
7797         custom_mac = 1;
7798       else if (unformat (i, "id %u", &id))
7799         ;
7800       else
7801         break;
7802     }
7803
7804   if (mode_is_set == 0)
7805     {
7806       errmsg ("Missing bond mode. ");
7807       return -99;
7808     }
7809
7810   /* Construct the API message */
7811   M (BOND_CREATE, mp);
7812
7813   mp->use_custom_mac = custom_mac;
7814
7815   mp->mode = mode;
7816   mp->lb = lb;
7817   mp->id = htonl (id);
7818
7819   if (custom_mac)
7820     clib_memcpy (mp->mac_address, mac_address, 6);
7821
7822   /* send it... */
7823   S (mp);
7824
7825   /* Wait for a reply... */
7826   W (ret);
7827   return ret;
7828 }
7829
7830 static int
7831 api_bond_delete (vat_main_t * vam)
7832 {
7833   unformat_input_t *i = vam->input;
7834   vl_api_bond_delete_t *mp;
7835   u32 sw_if_index = ~0;
7836   u8 sw_if_index_set = 0;
7837   int ret;
7838
7839   /* Parse args required to build the message */
7840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7841     {
7842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7843         sw_if_index_set = 1;
7844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7845         sw_if_index_set = 1;
7846       else
7847         break;
7848     }
7849
7850   if (sw_if_index_set == 0)
7851     {
7852       errmsg ("missing vpp interface name. ");
7853       return -99;
7854     }
7855
7856   /* Construct the API message */
7857   M (BOND_DELETE, mp);
7858
7859   mp->sw_if_index = ntohl (sw_if_index);
7860
7861   /* send it... */
7862   S (mp);
7863
7864   /* Wait for a reply... */
7865   W (ret);
7866   return ret;
7867 }
7868
7869 static int
7870 api_bond_enslave (vat_main_t * vam)
7871 {
7872   unformat_input_t *i = vam->input;
7873   vl_api_bond_enslave_t *mp;
7874   u32 bond_sw_if_index;
7875   int ret;
7876   u8 is_passive;
7877   u8 is_long_timeout;
7878   u32 bond_sw_if_index_is_set = 0;
7879   u32 sw_if_index;
7880   u8 sw_if_index_is_set = 0;
7881
7882   /* Parse args required to build the message */
7883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7884     {
7885       if (unformat (i, "sw_if_index %d", &sw_if_index))
7886         sw_if_index_is_set = 1;
7887       else if (unformat (i, "bond %u", &bond_sw_if_index))
7888         bond_sw_if_index_is_set = 1;
7889       else if (unformat (i, "passive %d", &is_passive))
7890         ;
7891       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7892         ;
7893       else
7894         break;
7895     }
7896
7897   if (bond_sw_if_index_is_set == 0)
7898     {
7899       errmsg ("Missing bond sw_if_index. ");
7900       return -99;
7901     }
7902   if (sw_if_index_is_set == 0)
7903     {
7904       errmsg ("Missing slave sw_if_index. ");
7905       return -99;
7906     }
7907
7908   /* Construct the API message */
7909   M (BOND_ENSLAVE, mp);
7910
7911   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7912   mp->sw_if_index = ntohl (sw_if_index);
7913   mp->is_long_timeout = is_long_timeout;
7914   mp->is_passive = is_passive;
7915
7916   /* send it... */
7917   S (mp);
7918
7919   /* Wait for a reply... */
7920   W (ret);
7921   return ret;
7922 }
7923
7924 static int
7925 api_bond_detach_slave (vat_main_t * vam)
7926 {
7927   unformat_input_t *i = vam->input;
7928   vl_api_bond_detach_slave_t *mp;
7929   u32 sw_if_index = ~0;
7930   u8 sw_if_index_set = 0;
7931   int ret;
7932
7933   /* Parse args required to build the message */
7934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7937         sw_if_index_set = 1;
7938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7939         sw_if_index_set = 1;
7940       else
7941         break;
7942     }
7943
7944   if (sw_if_index_set == 0)
7945     {
7946       errmsg ("missing vpp interface name. ");
7947       return -99;
7948     }
7949
7950   /* Construct the API message */
7951   M (BOND_DETACH_SLAVE, mp);
7952
7953   mp->sw_if_index = ntohl (sw_if_index);
7954
7955   /* send it... */
7956   S (mp);
7957
7958   /* Wait for a reply... */
7959   W (ret);
7960   return ret;
7961 }
7962
7963 static int
7964 api_ip_table_add_del (vat_main_t * vam)
7965 {
7966   unformat_input_t *i = vam->input;
7967   vl_api_ip_table_add_del_t *mp;
7968   u32 table_id = ~0;
7969   u8 is_ipv6 = 0;
7970   u8 is_add = 1;
7971   int ret = 0;
7972
7973   /* Parse args required to build the message */
7974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7975     {
7976       if (unformat (i, "ipv6"))
7977         is_ipv6 = 1;
7978       else if (unformat (i, "del"))
7979         is_add = 0;
7980       else if (unformat (i, "add"))
7981         is_add = 1;
7982       else if (unformat (i, "table %d", &table_id))
7983         ;
7984       else
7985         {
7986           clib_warning ("parse error '%U'", format_unformat_error, i);
7987           return -99;
7988         }
7989     }
7990
7991   if (~0 == table_id)
7992     {
7993       errmsg ("missing table-ID");
7994       return -99;
7995     }
7996
7997   /* Construct the API message */
7998   M (IP_TABLE_ADD_DEL, mp);
7999
8000   mp->table_id = ntohl (table_id);
8001   mp->is_ipv6 = is_ipv6;
8002   mp->is_add = is_add;
8003
8004   /* send it... */
8005   S (mp);
8006
8007   /* Wait for a reply... */
8008   W (ret);
8009
8010   return ret;
8011 }
8012
8013 static int
8014 api_ip_add_del_route (vat_main_t * vam)
8015 {
8016   unformat_input_t *i = vam->input;
8017   vl_api_ip_add_del_route_t *mp;
8018   u32 sw_if_index = ~0, vrf_id = 0;
8019   u8 is_ipv6 = 0;
8020   u8 is_local = 0, is_drop = 0;
8021   u8 is_unreach = 0, is_prohibit = 0;
8022   u8 is_add = 1;
8023   u32 next_hop_weight = 1;
8024   u8 is_multipath = 0;
8025   u8 address_set = 0;
8026   u8 address_length_set = 0;
8027   u32 next_hop_table_id = 0;
8028   u32 resolve_attempts = 0;
8029   u32 dst_address_length = 0;
8030   u8 next_hop_set = 0;
8031   ip4_address_t v4_dst_address, v4_next_hop_address;
8032   ip6_address_t v6_dst_address, v6_next_hop_address;
8033   int count = 1;
8034   int j;
8035   f64 before = 0;
8036   u32 random_add_del = 0;
8037   u32 *random_vector = 0;
8038   uword *random_hash;
8039   u32 random_seed = 0xdeaddabe;
8040   u32 classify_table_index = ~0;
8041   u8 is_classify = 0;
8042   u8 resolve_host = 0, resolve_attached = 0;
8043   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8044   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8045   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8046
8047   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8048   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8049   /* Parse args required to build the message */
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8053         ;
8054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8055         ;
8056       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8057         {
8058           address_set = 1;
8059           is_ipv6 = 0;
8060         }
8061       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8062         {
8063           address_set = 1;
8064           is_ipv6 = 1;
8065         }
8066       else if (unformat (i, "/%d", &dst_address_length))
8067         {
8068           address_length_set = 1;
8069         }
8070
8071       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8072                                          &v4_next_hop_address))
8073         {
8074           next_hop_set = 1;
8075         }
8076       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8077                                          &v6_next_hop_address))
8078         {
8079           next_hop_set = 1;
8080         }
8081       else
8082         if (unformat
8083             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8084         {
8085           next_hop_set = 1;
8086         }
8087       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8088         {
8089           next_hop_set = 1;
8090         }
8091       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8092         ;
8093       else if (unformat (i, "weight %d", &next_hop_weight))
8094         ;
8095       else if (unformat (i, "drop"))
8096         {
8097           is_drop = 1;
8098         }
8099       else if (unformat (i, "null-send-unreach"))
8100         {
8101           is_unreach = 1;
8102         }
8103       else if (unformat (i, "null-send-prohibit"))
8104         {
8105           is_prohibit = 1;
8106         }
8107       else if (unformat (i, "local"))
8108         {
8109           is_local = 1;
8110         }
8111       else if (unformat (i, "classify %d", &classify_table_index))
8112         {
8113           is_classify = 1;
8114         }
8115       else if (unformat (i, "del"))
8116         is_add = 0;
8117       else if (unformat (i, "add"))
8118         is_add = 1;
8119       else if (unformat (i, "resolve-via-host"))
8120         resolve_host = 1;
8121       else if (unformat (i, "resolve-via-attached"))
8122         resolve_attached = 1;
8123       else if (unformat (i, "multipath"))
8124         is_multipath = 1;
8125       else if (unformat (i, "vrf %d", &vrf_id))
8126         ;
8127       else if (unformat (i, "count %d", &count))
8128         ;
8129       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8130         ;
8131       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8132         ;
8133       else if (unformat (i, "out-label %d", &next_hop_out_label))
8134         {
8135           vl_api_fib_mpls_label_t fib_label = {
8136             .label = ntohl (next_hop_out_label),
8137             .ttl = 64,
8138             .exp = 0,
8139           };
8140           vec_add1 (next_hop_out_label_stack, fib_label);
8141         }
8142       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8143         ;
8144       else if (unformat (i, "random"))
8145         random_add_del = 1;
8146       else if (unformat (i, "seed %d", &random_seed))
8147         ;
8148       else
8149         {
8150           clib_warning ("parse error '%U'", format_unformat_error, i);
8151           return -99;
8152         }
8153     }
8154
8155   if (!next_hop_set && !is_drop && !is_local &&
8156       !is_classify && !is_unreach && !is_prohibit &&
8157       MPLS_LABEL_INVALID == next_hop_via_label)
8158     {
8159       errmsg
8160         ("next hop / local / drop / unreach / prohibit / classify not set");
8161       return -99;
8162     }
8163
8164   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8165     {
8166       errmsg ("next hop and next-hop via label set");
8167       return -99;
8168     }
8169   if (address_set == 0)
8170     {
8171       errmsg ("missing addresses");
8172       return -99;
8173     }
8174
8175   if (address_length_set == 0)
8176     {
8177       errmsg ("missing address length");
8178       return -99;
8179     }
8180
8181   /* Generate a pile of unique, random routes */
8182   if (random_add_del)
8183     {
8184       u32 this_random_address;
8185       random_hash = hash_create (count, sizeof (uword));
8186
8187       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8188       for (j = 0; j <= count; j++)
8189         {
8190           do
8191             {
8192               this_random_address = random_u32 (&random_seed);
8193               this_random_address =
8194                 clib_host_to_net_u32 (this_random_address);
8195             }
8196           while (hash_get (random_hash, this_random_address));
8197           vec_add1 (random_vector, this_random_address);
8198           hash_set (random_hash, this_random_address, 1);
8199         }
8200       hash_free (random_hash);
8201       v4_dst_address.as_u32 = random_vector[0];
8202     }
8203
8204   if (count > 1)
8205     {
8206       /* Turn on async mode */
8207       vam->async_mode = 1;
8208       vam->async_errors = 0;
8209       before = vat_time_now (vam);
8210     }
8211
8212   for (j = 0; j < count; j++)
8213     {
8214       /* Construct the API message */
8215       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8216           vec_len (next_hop_out_label_stack));
8217
8218       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8219       mp->table_id = ntohl (vrf_id);
8220
8221       mp->is_add = is_add;
8222       mp->is_drop = is_drop;
8223       mp->is_unreach = is_unreach;
8224       mp->is_prohibit = is_prohibit;
8225       mp->is_ipv6 = is_ipv6;
8226       mp->is_local = is_local;
8227       mp->is_classify = is_classify;
8228       mp->is_multipath = is_multipath;
8229       mp->is_resolve_host = resolve_host;
8230       mp->is_resolve_attached = resolve_attached;
8231       mp->next_hop_weight = next_hop_weight;
8232       mp->next_hop_preference = 0;
8233       mp->dst_address_length = dst_address_length;
8234       mp->next_hop_table_id = ntohl (next_hop_table_id);
8235       mp->classify_table_index = ntohl (classify_table_index);
8236       mp->next_hop_via_label = ntohl (next_hop_via_label);
8237       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8238       if (0 != mp->next_hop_n_out_labels)
8239         {
8240           memcpy (mp->next_hop_out_label_stack,
8241                   next_hop_out_label_stack,
8242                   (vec_len (next_hop_out_label_stack) *
8243                    sizeof (vl_api_fib_mpls_label_t)));
8244           vec_free (next_hop_out_label_stack);
8245         }
8246
8247       if (is_ipv6)
8248         {
8249           clib_memcpy (mp->dst_address, &v6_dst_address,
8250                        sizeof (v6_dst_address));
8251           if (next_hop_set)
8252             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8253                          sizeof (v6_next_hop_address));
8254           increment_v6_address (&v6_dst_address);
8255         }
8256       else
8257         {
8258           clib_memcpy (mp->dst_address, &v4_dst_address,
8259                        sizeof (v4_dst_address));
8260           if (next_hop_set)
8261             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8262                          sizeof (v4_next_hop_address));
8263           if (random_add_del)
8264             v4_dst_address.as_u32 = random_vector[j + 1];
8265           else
8266             increment_v4_address (&v4_dst_address);
8267         }
8268       /* send it... */
8269       S (mp);
8270       /* If we receive SIGTERM, stop now... */
8271       if (vam->do_exit)
8272         break;
8273     }
8274
8275   /* When testing multiple add/del ops, use a control-ping to sync */
8276   if (count > 1)
8277     {
8278       vl_api_control_ping_t *mp_ping;
8279       f64 after;
8280       f64 timeout;
8281
8282       /* Shut off async mode */
8283       vam->async_mode = 0;
8284
8285       MPING (CONTROL_PING, mp_ping);
8286       S (mp_ping);
8287
8288       timeout = vat_time_now (vam) + 1.0;
8289       while (vat_time_now (vam) < timeout)
8290         if (vam->result_ready == 1)
8291           goto out;
8292       vam->retval = -99;
8293
8294     out:
8295       if (vam->retval == -99)
8296         errmsg ("timeout");
8297
8298       if (vam->async_errors > 0)
8299         {
8300           errmsg ("%d asynchronous errors", vam->async_errors);
8301           vam->retval = -98;
8302         }
8303       vam->async_errors = 0;
8304       after = vat_time_now (vam);
8305
8306       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8307       if (j > 0)
8308         count = j;
8309
8310       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8311              count, after - before, count / (after - before));
8312     }
8313   else
8314     {
8315       int ret;
8316
8317       /* Wait for a reply... */
8318       W (ret);
8319       return ret;
8320     }
8321
8322   /* Return the good/bad news */
8323   return (vam->retval);
8324 }
8325
8326 static int
8327 api_ip_mroute_add_del (vat_main_t * vam)
8328 {
8329   unformat_input_t *i = vam->input;
8330   vl_api_ip_mroute_add_del_t *mp;
8331   u32 sw_if_index = ~0, vrf_id = 0;
8332   u8 is_ipv6 = 0;
8333   u8 is_local = 0;
8334   u8 is_add = 1;
8335   u8 address_set = 0;
8336   u32 grp_address_length = 0;
8337   ip4_address_t v4_grp_address, v4_src_address;
8338   ip6_address_t v6_grp_address, v6_src_address;
8339   mfib_itf_flags_t iflags = 0;
8340   mfib_entry_flags_t eflags = 0;
8341   int ret;
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         ;
8348       else if (unformat (i, "%U %U",
8349                          unformat_ip4_address, &v4_src_address,
8350                          unformat_ip4_address, &v4_grp_address))
8351         {
8352           grp_address_length = 64;
8353           address_set = 1;
8354           is_ipv6 = 0;
8355         }
8356       else if (unformat (i, "%U %U",
8357                          unformat_ip6_address, &v6_src_address,
8358                          unformat_ip6_address, &v6_grp_address))
8359         {
8360           grp_address_length = 256;
8361           address_set = 1;
8362           is_ipv6 = 1;
8363         }
8364       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8365         {
8366           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8367           grp_address_length = 32;
8368           address_set = 1;
8369           is_ipv6 = 0;
8370         }
8371       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8372         {
8373           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8374           grp_address_length = 128;
8375           address_set = 1;
8376           is_ipv6 = 1;
8377         }
8378       else if (unformat (i, "/%d", &grp_address_length))
8379         ;
8380       else if (unformat (i, "local"))
8381         {
8382           is_local = 1;
8383         }
8384       else if (unformat (i, "del"))
8385         is_add = 0;
8386       else if (unformat (i, "add"))
8387         is_add = 1;
8388       else if (unformat (i, "vrf %d", &vrf_id))
8389         ;
8390       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8391         ;
8392       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8393         ;
8394       else
8395         {
8396           clib_warning ("parse error '%U'", format_unformat_error, i);
8397           return -99;
8398         }
8399     }
8400
8401   if (address_set == 0)
8402     {
8403       errmsg ("missing addresses\n");
8404       return -99;
8405     }
8406
8407   /* Construct the API message */
8408   M (IP_MROUTE_ADD_DEL, mp);
8409
8410   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8411   mp->table_id = ntohl (vrf_id);
8412
8413   mp->is_add = is_add;
8414   mp->is_ipv6 = is_ipv6;
8415   mp->is_local = is_local;
8416   mp->itf_flags = ntohl (iflags);
8417   mp->entry_flags = ntohl (eflags);
8418   mp->grp_address_length = grp_address_length;
8419   mp->grp_address_length = ntohs (mp->grp_address_length);
8420
8421   if (is_ipv6)
8422     {
8423       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8424       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8425     }
8426   else
8427     {
8428       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8429       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8430
8431     }
8432
8433   /* send it... */
8434   S (mp);
8435   /* Wait for a reply... */
8436   W (ret);
8437   return ret;
8438 }
8439
8440 static int
8441 api_mpls_table_add_del (vat_main_t * vam)
8442 {
8443   unformat_input_t *i = vam->input;
8444   vl_api_mpls_table_add_del_t *mp;
8445   u32 table_id = ~0;
8446   u8 is_add = 1;
8447   int ret = 0;
8448
8449   /* Parse args required to build the message */
8450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8451     {
8452       if (unformat (i, "table %d", &table_id))
8453         ;
8454       else if (unformat (i, "del"))
8455         is_add = 0;
8456       else if (unformat (i, "add"))
8457         is_add = 1;
8458       else
8459         {
8460           clib_warning ("parse error '%U'", format_unformat_error, i);
8461           return -99;
8462         }
8463     }
8464
8465   if (~0 == table_id)
8466     {
8467       errmsg ("missing table-ID");
8468       return -99;
8469     }
8470
8471   /* Construct the API message */
8472   M (MPLS_TABLE_ADD_DEL, mp);
8473
8474   mp->mt_table_id = ntohl (table_id);
8475   mp->mt_is_add = is_add;
8476
8477   /* send it... */
8478   S (mp);
8479
8480   /* Wait for a reply... */
8481   W (ret);
8482
8483   return ret;
8484 }
8485
8486 static int
8487 api_mpls_route_add_del (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_mpls_route_add_del_t *mp;
8491   u32 sw_if_index = ~0, table_id = 0;
8492   u8 is_add = 1;
8493   u32 next_hop_weight = 1;
8494   u8 is_multipath = 0;
8495   u32 next_hop_table_id = 0;
8496   u8 next_hop_set = 0;
8497   ip4_address_t v4_next_hop_address = {
8498     .as_u32 = 0,
8499   };
8500   ip6_address_t v6_next_hop_address = { {0} };
8501   int count = 1;
8502   int j;
8503   f64 before = 0;
8504   u32 classify_table_index = ~0;
8505   u8 is_classify = 0;
8506   u8 resolve_host = 0, resolve_attached = 0;
8507   u8 is_interface_rx = 0;
8508   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8509   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8510   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8511   mpls_label_t local_label = MPLS_LABEL_INVALID;
8512   u8 is_eos = 0;
8513   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8514
8515   /* Parse args required to build the message */
8516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8517     {
8518       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8519         ;
8520       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8521         ;
8522       else if (unformat (i, "%d", &local_label))
8523         ;
8524       else if (unformat (i, "eos"))
8525         is_eos = 1;
8526       else if (unformat (i, "non-eos"))
8527         is_eos = 0;
8528       else if (unformat (i, "via %U", unformat_ip4_address,
8529                          &v4_next_hop_address))
8530         {
8531           next_hop_set = 1;
8532           next_hop_proto = DPO_PROTO_IP4;
8533         }
8534       else if (unformat (i, "via %U", unformat_ip6_address,
8535                          &v6_next_hop_address))
8536         {
8537           next_hop_set = 1;
8538           next_hop_proto = DPO_PROTO_IP6;
8539         }
8540       else if (unformat (i, "weight %d", &next_hop_weight))
8541         ;
8542       else if (unformat (i, "classify %d", &classify_table_index))
8543         {
8544           is_classify = 1;
8545         }
8546       else if (unformat (i, "del"))
8547         is_add = 0;
8548       else if (unformat (i, "add"))
8549         is_add = 1;
8550       else if (unformat (i, "resolve-via-host"))
8551         resolve_host = 1;
8552       else if (unformat (i, "resolve-via-attached"))
8553         resolve_attached = 1;
8554       else if (unformat (i, "multipath"))
8555         is_multipath = 1;
8556       else if (unformat (i, "count %d", &count))
8557         ;
8558       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8559         {
8560           next_hop_set = 1;
8561           next_hop_proto = DPO_PROTO_IP4;
8562         }
8563       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8564         {
8565           next_hop_set = 1;
8566           next_hop_proto = DPO_PROTO_IP6;
8567         }
8568       else
8569         if (unformat
8570             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8571              &sw_if_index))
8572         {
8573           next_hop_set = 1;
8574           next_hop_proto = DPO_PROTO_ETHERNET;
8575           is_interface_rx = 1;
8576         }
8577       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8578         {
8579           next_hop_set = 1;
8580           next_hop_proto = DPO_PROTO_ETHERNET;
8581           is_interface_rx = 1;
8582         }
8583       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8584         next_hop_set = 1;
8585       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8586         next_hop_set = 1;
8587       else if (unformat (i, "out-label %d", &next_hop_out_label))
8588         {
8589           vl_api_fib_mpls_label_t fib_label = {
8590             .label = ntohl (next_hop_out_label),
8591             .ttl = 64,
8592             .exp = 0,
8593           };
8594           vec_add1 (next_hop_out_label_stack, fib_label);
8595         }
8596       else
8597         {
8598           clib_warning ("parse error '%U'", format_unformat_error, i);
8599           return -99;
8600         }
8601     }
8602
8603   if (!next_hop_set && !is_classify)
8604     {
8605       errmsg ("next hop / classify not set");
8606       return -99;
8607     }
8608
8609   if (MPLS_LABEL_INVALID == local_label)
8610     {
8611       errmsg ("missing label");
8612       return -99;
8613     }
8614
8615   if (count > 1)
8616     {
8617       /* Turn on async mode */
8618       vam->async_mode = 1;
8619       vam->async_errors = 0;
8620       before = vat_time_now (vam);
8621     }
8622
8623   for (j = 0; j < count; j++)
8624     {
8625       /* Construct the API message */
8626       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8627           vec_len (next_hop_out_label_stack));
8628
8629       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8630       mp->mr_table_id = ntohl (table_id);
8631
8632       mp->mr_is_add = is_add;
8633       mp->mr_next_hop_proto = next_hop_proto;
8634       mp->mr_is_classify = is_classify;
8635       mp->mr_is_multipath = is_multipath;
8636       mp->mr_is_resolve_host = resolve_host;
8637       mp->mr_is_resolve_attached = resolve_attached;
8638       mp->mr_is_interface_rx = is_interface_rx;
8639       mp->mr_next_hop_weight = next_hop_weight;
8640       mp->mr_next_hop_preference = 0;
8641       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8642       mp->mr_classify_table_index = ntohl (classify_table_index);
8643       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8644       mp->mr_label = ntohl (local_label);
8645       mp->mr_eos = is_eos;
8646
8647       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8648       if (0 != mp->mr_next_hop_n_out_labels)
8649         {
8650           memcpy (mp->mr_next_hop_out_label_stack,
8651                   next_hop_out_label_stack,
8652                   vec_len (next_hop_out_label_stack) *
8653                   sizeof (vl_api_fib_mpls_label_t));
8654           vec_free (next_hop_out_label_stack);
8655         }
8656
8657       if (next_hop_set)
8658         {
8659           if (DPO_PROTO_IP4 == next_hop_proto)
8660             {
8661               clib_memcpy (mp->mr_next_hop,
8662                            &v4_next_hop_address,
8663                            sizeof (v4_next_hop_address));
8664             }
8665           else if (DPO_PROTO_IP6 == next_hop_proto)
8666
8667             {
8668               clib_memcpy (mp->mr_next_hop,
8669                            &v6_next_hop_address,
8670                            sizeof (v6_next_hop_address));
8671             }
8672         }
8673       local_label++;
8674
8675       /* send it... */
8676       S (mp);
8677       /* If we receive SIGTERM, stop now... */
8678       if (vam->do_exit)
8679         break;
8680     }
8681
8682   /* When testing multiple add/del ops, use a control-ping to sync */
8683   if (count > 1)
8684     {
8685       vl_api_control_ping_t *mp_ping;
8686       f64 after;
8687       f64 timeout;
8688
8689       /* Shut off async mode */
8690       vam->async_mode = 0;
8691
8692       MPING (CONTROL_PING, mp_ping);
8693       S (mp_ping);
8694
8695       timeout = vat_time_now (vam) + 1.0;
8696       while (vat_time_now (vam) < timeout)
8697         if (vam->result_ready == 1)
8698           goto out;
8699       vam->retval = -99;
8700
8701     out:
8702       if (vam->retval == -99)
8703         errmsg ("timeout");
8704
8705       if (vam->async_errors > 0)
8706         {
8707           errmsg ("%d asynchronous errors", vam->async_errors);
8708           vam->retval = -98;
8709         }
8710       vam->async_errors = 0;
8711       after = vat_time_now (vam);
8712
8713       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8714       if (j > 0)
8715         count = j;
8716
8717       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8718              count, after - before, count / (after - before));
8719     }
8720   else
8721     {
8722       int ret;
8723
8724       /* Wait for a reply... */
8725       W (ret);
8726       return ret;
8727     }
8728
8729   /* Return the good/bad news */
8730   return (vam->retval);
8731 }
8732
8733 static int
8734 api_mpls_ip_bind_unbind (vat_main_t * vam)
8735 {
8736   unformat_input_t *i = vam->input;
8737   vl_api_mpls_ip_bind_unbind_t *mp;
8738   u32 ip_table_id = 0;
8739   u8 is_bind = 1;
8740   u8 is_ip4 = 1;
8741   ip4_address_t v4_address;
8742   ip6_address_t v6_address;
8743   u32 address_length;
8744   u8 address_set = 0;
8745   mpls_label_t local_label = MPLS_LABEL_INVALID;
8746   int ret;
8747
8748   /* Parse args required to build the message */
8749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8750     {
8751       if (unformat (i, "%U/%d", unformat_ip4_address,
8752                     &v4_address, &address_length))
8753         {
8754           is_ip4 = 1;
8755           address_set = 1;
8756         }
8757       else if (unformat (i, "%U/%d", unformat_ip6_address,
8758                          &v6_address, &address_length))
8759         {
8760           is_ip4 = 0;
8761           address_set = 1;
8762         }
8763       else if (unformat (i, "%d", &local_label))
8764         ;
8765       else if (unformat (i, "table-id %d", &ip_table_id))
8766         ;
8767       else if (unformat (i, "unbind"))
8768         is_bind = 0;
8769       else if (unformat (i, "bind"))
8770         is_bind = 1;
8771       else
8772         {
8773           clib_warning ("parse error '%U'", format_unformat_error, i);
8774           return -99;
8775         }
8776     }
8777
8778   if (!address_set)
8779     {
8780       errmsg ("IP address not set");
8781       return -99;
8782     }
8783
8784   if (MPLS_LABEL_INVALID == local_label)
8785     {
8786       errmsg ("missing label");
8787       return -99;
8788     }
8789
8790   /* Construct the API message */
8791   M (MPLS_IP_BIND_UNBIND, mp);
8792
8793   mp->mb_is_bind = is_bind;
8794   mp->mb_is_ip4 = is_ip4;
8795   mp->mb_ip_table_id = ntohl (ip_table_id);
8796   mp->mb_mpls_table_id = 0;
8797   mp->mb_label = ntohl (local_label);
8798   mp->mb_address_length = address_length;
8799
8800   if (is_ip4)
8801     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8802   else
8803     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8804
8805   /* send it... */
8806   S (mp);
8807
8808   /* Wait for a reply... */
8809   W (ret);
8810   return ret;
8811 }
8812
8813 static int
8814 api_sr_mpls_policy_add (vat_main_t * vam)
8815 {
8816   unformat_input_t *i = vam->input;
8817   vl_api_sr_mpls_policy_add_t *mp;
8818   u32 bsid = 0;
8819   u32 weight = 1;
8820   u8 type = 0;
8821   u8 n_segments = 0;
8822   u32 sid;
8823   u32 *segments = NULL;
8824   int ret;
8825
8826   /* Parse args required to build the message */
8827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8828     {
8829       if (unformat (i, "bsid %d", &bsid))
8830         ;
8831       else if (unformat (i, "weight %d", &weight))
8832         ;
8833       else if (unformat (i, "spray"))
8834         type = 1;
8835       else if (unformat (i, "next %d", &sid))
8836         {
8837           n_segments += 1;
8838           vec_add1 (segments, htonl (sid));
8839         }
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (bsid == 0)
8848     {
8849       errmsg ("bsid not set");
8850       return -99;
8851     }
8852
8853   if (n_segments == 0)
8854     {
8855       errmsg ("no sid in segment stack");
8856       return -99;
8857     }
8858
8859   /* Construct the API message */
8860   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8861
8862   mp->bsid = htonl (bsid);
8863   mp->weight = htonl (weight);
8864   mp->type = type;
8865   mp->n_segments = n_segments;
8866   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8867   vec_free (segments);
8868
8869   /* send it... */
8870   S (mp);
8871
8872   /* Wait for a reply... */
8873   W (ret);
8874   return ret;
8875 }
8876
8877 static int
8878 api_sr_mpls_policy_del (vat_main_t * vam)
8879 {
8880   unformat_input_t *i = vam->input;
8881   vl_api_sr_mpls_policy_del_t *mp;
8882   u32 bsid = 0;
8883   int ret;
8884
8885   /* Parse args required to build the message */
8886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8887     {
8888       if (unformat (i, "bsid %d", &bsid))
8889         ;
8890       else
8891         {
8892           clib_warning ("parse error '%U'", format_unformat_error, i);
8893           return -99;
8894         }
8895     }
8896
8897   if (bsid == 0)
8898     {
8899       errmsg ("bsid not set");
8900       return -99;
8901     }
8902
8903   /* Construct the API message */
8904   M (SR_MPLS_POLICY_DEL, mp);
8905
8906   mp->bsid = htonl (bsid);
8907
8908   /* send it... */
8909   S (mp);
8910
8911   /* Wait for a reply... */
8912   W (ret);
8913   return ret;
8914 }
8915
8916 static int
8917 api_bier_table_add_del (vat_main_t * vam)
8918 {
8919   unformat_input_t *i = vam->input;
8920   vl_api_bier_table_add_del_t *mp;
8921   u8 is_add = 1;
8922   u32 set = 0, sub_domain = 0, hdr_len = 3;
8923   mpls_label_t local_label = MPLS_LABEL_INVALID;
8924   int ret;
8925
8926   /* Parse args required to build the message */
8927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8928     {
8929       if (unformat (i, "sub-domain %d", &sub_domain))
8930         ;
8931       else if (unformat (i, "set %d", &set))
8932         ;
8933       else if (unformat (i, "label %d", &local_label))
8934         ;
8935       else if (unformat (i, "hdr-len %d", &hdr_len))
8936         ;
8937       else if (unformat (i, "add"))
8938         is_add = 1;
8939       else if (unformat (i, "del"))
8940         is_add = 0;
8941       else
8942         {
8943           clib_warning ("parse error '%U'", format_unformat_error, i);
8944           return -99;
8945         }
8946     }
8947
8948   if (MPLS_LABEL_INVALID == local_label)
8949     {
8950       errmsg ("missing label\n");
8951       return -99;
8952     }
8953
8954   /* Construct the API message */
8955   M (BIER_TABLE_ADD_DEL, mp);
8956
8957   mp->bt_is_add = is_add;
8958   mp->bt_label = ntohl (local_label);
8959   mp->bt_tbl_id.bt_set = set;
8960   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8961   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8962
8963   /* send it... */
8964   S (mp);
8965
8966   /* Wait for a reply... */
8967   W (ret);
8968
8969   return (ret);
8970 }
8971
8972 static int
8973 api_bier_route_add_del (vat_main_t * vam)
8974 {
8975   unformat_input_t *i = vam->input;
8976   vl_api_bier_route_add_del_t *mp;
8977   u8 is_add = 1;
8978   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8979   ip4_address_t v4_next_hop_address;
8980   ip6_address_t v6_next_hop_address;
8981   u8 next_hop_set = 0;
8982   u8 next_hop_proto_is_ip4 = 1;
8983   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8984   int ret;
8985
8986   /* Parse args required to build the message */
8987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8988     {
8989       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8990         {
8991           next_hop_proto_is_ip4 = 1;
8992           next_hop_set = 1;
8993         }
8994       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8995         {
8996           next_hop_proto_is_ip4 = 0;
8997           next_hop_set = 1;
8998         }
8999       if (unformat (i, "sub-domain %d", &sub_domain))
9000         ;
9001       else if (unformat (i, "set %d", &set))
9002         ;
9003       else if (unformat (i, "hdr-len %d", &hdr_len))
9004         ;
9005       else if (unformat (i, "bp %d", &bp))
9006         ;
9007       else if (unformat (i, "add"))
9008         is_add = 1;
9009       else if (unformat (i, "del"))
9010         is_add = 0;
9011       else if (unformat (i, "out-label %d", &next_hop_out_label))
9012         ;
9013       else
9014         {
9015           clib_warning ("parse error '%U'", format_unformat_error, i);
9016           return -99;
9017         }
9018     }
9019
9020   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9021     {
9022       errmsg ("next hop / label set\n");
9023       return -99;
9024     }
9025   if (0 == bp)
9026     {
9027       errmsg ("bit=position not set\n");
9028       return -99;
9029     }
9030
9031   /* Construct the API message */
9032   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9033
9034   mp->br_is_add = is_add;
9035   mp->br_tbl_id.bt_set = set;
9036   mp->br_tbl_id.bt_sub_domain = sub_domain;
9037   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9038   mp->br_bp = ntohs (bp);
9039   mp->br_n_paths = 1;
9040   mp->br_paths[0].n_labels = 1;
9041   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9042   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9043
9044   if (next_hop_proto_is_ip4)
9045     {
9046       clib_memcpy (mp->br_paths[0].next_hop,
9047                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9048     }
9049   else
9050     {
9051       clib_memcpy (mp->br_paths[0].next_hop,
9052                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9053     }
9054
9055   /* send it... */
9056   S (mp);
9057
9058   /* Wait for a reply... */
9059   W (ret);
9060
9061   return (ret);
9062 }
9063
9064 static int
9065 api_proxy_arp_add_del (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_proxy_arp_add_del_t *mp;
9069   u32 vrf_id = 0;
9070   u8 is_add = 1;
9071   vl_api_ip4_address_t lo, hi;
9072   u8 range_set = 0;
9073   int ret;
9074
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "vrf %d", &vrf_id))
9078         ;
9079       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9080                          unformat_vl_api_ip4_address, &hi))
9081         range_set = 1;
9082       else if (unformat (i, "del"))
9083         is_add = 0;
9084       else
9085         {
9086           clib_warning ("parse error '%U'", format_unformat_error, i);
9087           return -99;
9088         }
9089     }
9090
9091   if (range_set == 0)
9092     {
9093       errmsg ("address range not set");
9094       return -99;
9095     }
9096
9097   M (PROXY_ARP_ADD_DEL, mp);
9098
9099   mp->proxy.table_id = ntohl (vrf_id);
9100   mp->is_add = is_add;
9101   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9102   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9103
9104   S (mp);
9105   W (ret);
9106   return ret;
9107 }
9108
9109 static int
9110 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9114   u32 sw_if_index;
9115   u8 enable = 1;
9116   u8 sw_if_index_set = 0;
9117   int ret;
9118
9119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9120     {
9121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9122         sw_if_index_set = 1;
9123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9124         sw_if_index_set = 1;
9125       else if (unformat (i, "enable"))
9126         enable = 1;
9127       else if (unformat (i, "disable"))
9128         enable = 0;
9129       else
9130         {
9131           clib_warning ("parse error '%U'", format_unformat_error, i);
9132           return -99;
9133         }
9134     }
9135
9136   if (sw_if_index_set == 0)
9137     {
9138       errmsg ("missing interface name or sw_if_index");
9139       return -99;
9140     }
9141
9142   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9143
9144   mp->sw_if_index = ntohl (sw_if_index);
9145   mp->enable_disable = enable;
9146
9147   S (mp);
9148   W (ret);
9149   return ret;
9150 }
9151
9152 static int
9153 api_mpls_tunnel_add_del (vat_main_t * vam)
9154 {
9155   unformat_input_t *i = vam->input;
9156   vl_api_mpls_tunnel_add_del_t *mp;
9157
9158   u8 is_add = 1;
9159   u8 l2_only = 0;
9160   u32 sw_if_index = ~0;
9161   u32 next_hop_sw_if_index = ~0;
9162   u32 next_hop_proto_is_ip4 = 1;
9163
9164   u32 next_hop_table_id = 0;
9165   ip4_address_t v4_next_hop_address = {
9166     .as_u32 = 0,
9167   };
9168   ip6_address_t v6_next_hop_address = { {0} };
9169   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9170   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9171   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9172   int ret;
9173
9174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (i, "add"))
9177         is_add = 1;
9178       else
9179         if (unformat
9180             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9181         is_add = 0;
9182       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9183         is_add = 0;
9184       else if (unformat (i, "via %U",
9185                          unformat_ip4_address, &v4_next_hop_address))
9186         {
9187           next_hop_proto_is_ip4 = 1;
9188         }
9189       else if (unformat (i, "via %U",
9190                          unformat_ip6_address, &v6_next_hop_address))
9191         {
9192           next_hop_proto_is_ip4 = 0;
9193         }
9194       else if (unformat (i, "via-label %d", &next_hop_via_label))
9195         ;
9196       else
9197         if (unformat
9198             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9199         ;
9200       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9201         ;
9202       else if (unformat (i, "l2-only"))
9203         l2_only = 1;
9204       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9205         ;
9206       else if (unformat (i, "out-label %d", &next_hop_out_label))
9207         {
9208           vl_api_fib_mpls_label_t fib_label = {
9209             .label = ntohl (next_hop_out_label),
9210             .ttl = 64,
9211             .exp = 0,
9212           };
9213           vec_add1 (next_hop_out_label_stack, fib_label);
9214         }
9215       else
9216         {
9217           clib_warning ("parse error '%U'", format_unformat_error, i);
9218           return -99;
9219         }
9220     }
9221
9222   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9223       vec_len (next_hop_out_label_stack));
9224
9225   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9226   mp->mt_sw_if_index = ntohl (sw_if_index);
9227   mp->mt_is_add = is_add;
9228   mp->mt_l2_only = l2_only;
9229   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9230   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9231   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9232   mp->mt_next_hop_weight = 1;
9233   mp->mt_next_hop_preference = 0;
9234
9235   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9236
9237   if (0 != mp->mt_next_hop_n_out_labels)
9238     {
9239       clib_memcpy (mp->mt_next_hop_out_label_stack,
9240                    next_hop_out_label_stack,
9241                    (vec_len (next_hop_out_label_stack) *
9242                     sizeof (vl_api_fib_mpls_label_t)));
9243       vec_free (next_hop_out_label_stack);
9244     }
9245
9246   if (next_hop_proto_is_ip4)
9247     {
9248       clib_memcpy (mp->mt_next_hop,
9249                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9250     }
9251   else
9252     {
9253       clib_memcpy (mp->mt_next_hop,
9254                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9255     }
9256
9257   S (mp);
9258   W (ret);
9259   return ret;
9260 }
9261
9262 static int
9263 api_sw_interface_set_unnumbered (vat_main_t * vam)
9264 {
9265   unformat_input_t *i = vam->input;
9266   vl_api_sw_interface_set_unnumbered_t *mp;
9267   u32 sw_if_index;
9268   u32 unnum_sw_index = ~0;
9269   u8 is_add = 1;
9270   u8 sw_if_index_set = 0;
9271   int ret;
9272
9273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9276         sw_if_index_set = 1;
9277       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9278         sw_if_index_set = 1;
9279       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9280         ;
9281       else if (unformat (i, "del"))
9282         is_add = 0;
9283       else
9284         {
9285           clib_warning ("parse error '%U'", format_unformat_error, i);
9286           return -99;
9287         }
9288     }
9289
9290   if (sw_if_index_set == 0)
9291     {
9292       errmsg ("missing interface name or sw_if_index");
9293       return -99;
9294     }
9295
9296   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9297
9298   mp->sw_if_index = ntohl (sw_if_index);
9299   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9300   mp->is_add = is_add;
9301
9302   S (mp);
9303   W (ret);
9304   return ret;
9305 }
9306
9307 static int
9308 api_ip_neighbor_add_del (vat_main_t * vam)
9309 {
9310   vl_api_mac_address_t mac_address;
9311   unformat_input_t *i = vam->input;
9312   vl_api_ip_neighbor_add_del_t *mp;
9313   vl_api_address_t ip_address;
9314   u32 sw_if_index;
9315   u8 sw_if_index_set = 0;
9316   u8 is_add = 1;
9317   u8 mac_set = 0;
9318   u8 address_set = 0;
9319   int ret;
9320   ip_neighbor_flags_t flags;
9321
9322   flags = IP_NEIGHBOR_FLAG_NONE;
9323   clib_memset (&ip_address, 0, sizeof (ip_address));
9324   clib_memset (&mac_address, 0, sizeof (mac_address));
9325   /* Parse args required to build the message */
9326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9327     {
9328       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9329         {
9330           mac_set = 1;
9331         }
9332       else if (unformat (i, "del"))
9333         is_add = 0;
9334       else
9335         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9336         sw_if_index_set = 1;
9337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9338         sw_if_index_set = 1;
9339       else if (unformat (i, "static"))
9340         flags |= IP_NEIGHBOR_FLAG_STATIC;
9341       else if (unformat (i, "no-fib-entry"))
9342         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9343       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9344         address_set = 1;
9345       else
9346         {
9347           clib_warning ("parse error '%U'", format_unformat_error, i);
9348           return -99;
9349         }
9350     }
9351
9352   if (sw_if_index_set == 0)
9353     {
9354       errmsg ("missing interface name or sw_if_index");
9355       return -99;
9356     }
9357   if (!address_set)
9358     {
9359       errmsg ("no address set");
9360       return -99;
9361     }
9362
9363   /* Construct the API message */
9364   M (IP_NEIGHBOR_ADD_DEL, mp);
9365
9366   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9367   mp->is_add = is_add;
9368   mp->neighbor.flags = htonl (flags);
9369   if (mac_set)
9370     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9371                  sizeof (mac_address));
9372   if (address_set)
9373     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9374
9375   /* send it... */
9376   S (mp);
9377
9378   /* Wait for a reply, return good/bad news  */
9379   W (ret);
9380   return ret;
9381 }
9382
9383 static int
9384 api_create_vlan_subif (vat_main_t * vam)
9385 {
9386   unformat_input_t *i = vam->input;
9387   vl_api_create_vlan_subif_t *mp;
9388   u32 sw_if_index;
9389   u8 sw_if_index_set = 0;
9390   u32 vlan_id;
9391   u8 vlan_id_set = 0;
9392   int ret;
9393
9394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9395     {
9396       if (unformat (i, "sw_if_index %d", &sw_if_index))
9397         sw_if_index_set = 1;
9398       else
9399         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9400         sw_if_index_set = 1;
9401       else if (unformat (i, "vlan %d", &vlan_id))
9402         vlan_id_set = 1;
9403       else
9404         {
9405           clib_warning ("parse error '%U'", format_unformat_error, i);
9406           return -99;
9407         }
9408     }
9409
9410   if (sw_if_index_set == 0)
9411     {
9412       errmsg ("missing interface name or sw_if_index");
9413       return -99;
9414     }
9415
9416   if (vlan_id_set == 0)
9417     {
9418       errmsg ("missing vlan_id");
9419       return -99;
9420     }
9421   M (CREATE_VLAN_SUBIF, mp);
9422
9423   mp->sw_if_index = ntohl (sw_if_index);
9424   mp->vlan_id = ntohl (vlan_id);
9425
9426   S (mp);
9427   W (ret);
9428   return ret;
9429 }
9430
9431 #define foreach_create_subif_bit                \
9432 _(no_tags)                                      \
9433 _(one_tag)                                      \
9434 _(two_tags)                                     \
9435 _(dot1ad)                                       \
9436 _(exact_match)                                  \
9437 _(default_sub)                                  \
9438 _(outer_vlan_id_any)                            \
9439 _(inner_vlan_id_any)
9440
9441 static int
9442 api_create_subif (vat_main_t * vam)
9443 {
9444   unformat_input_t *i = vam->input;
9445   vl_api_create_subif_t *mp;
9446   u32 sw_if_index;
9447   u8 sw_if_index_set = 0;
9448   u32 sub_id;
9449   u8 sub_id_set = 0;
9450   u32 no_tags = 0;
9451   u32 one_tag = 0;
9452   u32 two_tags = 0;
9453   u32 dot1ad = 0;
9454   u32 exact_match = 0;
9455   u32 default_sub = 0;
9456   u32 outer_vlan_id_any = 0;
9457   u32 inner_vlan_id_any = 0;
9458   u32 tmp;
9459   u16 outer_vlan_id = 0;
9460   u16 inner_vlan_id = 0;
9461   int ret;
9462
9463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9464     {
9465       if (unformat (i, "sw_if_index %d", &sw_if_index))
9466         sw_if_index_set = 1;
9467       else
9468         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9469         sw_if_index_set = 1;
9470       else if (unformat (i, "sub_id %d", &sub_id))
9471         sub_id_set = 1;
9472       else if (unformat (i, "outer_vlan_id %d", &tmp))
9473         outer_vlan_id = tmp;
9474       else if (unformat (i, "inner_vlan_id %d", &tmp))
9475         inner_vlan_id = tmp;
9476
9477 #define _(a) else if (unformat (i, #a)) a = 1 ;
9478       foreach_create_subif_bit
9479 #undef _
9480         else
9481         {
9482           clib_warning ("parse error '%U'", format_unformat_error, i);
9483           return -99;
9484         }
9485     }
9486
9487   if (sw_if_index_set == 0)
9488     {
9489       errmsg ("missing interface name or sw_if_index");
9490       return -99;
9491     }
9492
9493   if (sub_id_set == 0)
9494     {
9495       errmsg ("missing sub_id");
9496       return -99;
9497     }
9498   M (CREATE_SUBIF, mp);
9499
9500   mp->sw_if_index = ntohl (sw_if_index);
9501   mp->sub_id = ntohl (sub_id);
9502
9503 #define _(a) mp->a = a;
9504   foreach_create_subif_bit;
9505 #undef _
9506
9507   mp->outer_vlan_id = ntohs (outer_vlan_id);
9508   mp->inner_vlan_id = ntohs (inner_vlan_id);
9509
9510   S (mp);
9511   W (ret);
9512   return ret;
9513 }
9514
9515 static int
9516 api_reset_fib (vat_main_t * vam)
9517 {
9518   unformat_input_t *i = vam->input;
9519   vl_api_reset_fib_t *mp;
9520   u32 vrf_id = 0;
9521   u8 is_ipv6 = 0;
9522   u8 vrf_id_set = 0;
9523
9524   int ret;
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "vrf %d", &vrf_id))
9528         vrf_id_set = 1;
9529       else if (unformat (i, "ipv6"))
9530         is_ipv6 = 1;
9531       else
9532         {
9533           clib_warning ("parse error '%U'", format_unformat_error, i);
9534           return -99;
9535         }
9536     }
9537
9538   if (vrf_id_set == 0)
9539     {
9540       errmsg ("missing vrf id");
9541       return -99;
9542     }
9543
9544   M (RESET_FIB, mp);
9545
9546   mp->vrf_id = ntohl (vrf_id);
9547   mp->is_ipv6 = is_ipv6;
9548
9549   S (mp);
9550   W (ret);
9551   return ret;
9552 }
9553
9554 static int
9555 api_dhcp_proxy_config (vat_main_t * vam)
9556 {
9557   unformat_input_t *i = vam->input;
9558   vl_api_dhcp_proxy_config_t *mp;
9559   u32 rx_vrf_id = 0;
9560   u32 server_vrf_id = 0;
9561   u8 is_add = 1;
9562   u8 v4_address_set = 0;
9563   u8 v6_address_set = 0;
9564   ip4_address_t v4address;
9565   ip6_address_t v6address;
9566   u8 v4_src_address_set = 0;
9567   u8 v6_src_address_set = 0;
9568   ip4_address_t v4srcaddress;
9569   ip6_address_t v6srcaddress;
9570   int ret;
9571
9572   /* Parse args required to build the message */
9573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (i, "del"))
9576         is_add = 0;
9577       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9578         ;
9579       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9580         ;
9581       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9582         v4_address_set = 1;
9583       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9584         v6_address_set = 1;
9585       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9586         v4_src_address_set = 1;
9587       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9588         v6_src_address_set = 1;
9589       else
9590         break;
9591     }
9592
9593   if (v4_address_set && v6_address_set)
9594     {
9595       errmsg ("both v4 and v6 server addresses set");
9596       return -99;
9597     }
9598   if (!v4_address_set && !v6_address_set)
9599     {
9600       errmsg ("no server addresses set");
9601       return -99;
9602     }
9603
9604   if (v4_src_address_set && v6_src_address_set)
9605     {
9606       errmsg ("both v4 and v6  src addresses set");
9607       return -99;
9608     }
9609   if (!v4_src_address_set && !v6_src_address_set)
9610     {
9611       errmsg ("no src addresses set");
9612       return -99;
9613     }
9614
9615   if (!(v4_src_address_set && v4_address_set) &&
9616       !(v6_src_address_set && v6_address_set))
9617     {
9618       errmsg ("no matching server and src addresses set");
9619       return -99;
9620     }
9621
9622   /* Construct the API message */
9623   M (DHCP_PROXY_CONFIG, mp);
9624
9625   mp->is_add = is_add;
9626   mp->rx_vrf_id = ntohl (rx_vrf_id);
9627   mp->server_vrf_id = ntohl (server_vrf_id);
9628   if (v6_address_set)
9629     {
9630       mp->is_ipv6 = 1;
9631       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9632       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9633     }
9634   else
9635     {
9636       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9637       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9638     }
9639
9640   /* send it... */
9641   S (mp);
9642
9643   /* Wait for a reply, return good/bad news  */
9644   W (ret);
9645   return ret;
9646 }
9647
9648 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9649 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9650
9651 static void
9652 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9653 {
9654   vat_main_t *vam = &vat_main;
9655   u32 i, count = mp->count;
9656   vl_api_dhcp_server_t *s;
9657
9658   if (mp->is_ipv6)
9659     print (vam->ofp,
9660            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9661            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9662            ntohl (mp->rx_vrf_id),
9663            format_ip6_address, mp->dhcp_src_address,
9664            mp->vss_type, mp->vss_vpn_ascii_id,
9665            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9666   else
9667     print (vam->ofp,
9668            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9669            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9670            ntohl (mp->rx_vrf_id),
9671            format_ip4_address, mp->dhcp_src_address,
9672            mp->vss_type, mp->vss_vpn_ascii_id,
9673            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9674
9675   for (i = 0; i < count; i++)
9676     {
9677       s = &mp->servers[i];
9678
9679       if (mp->is_ipv6)
9680         print (vam->ofp,
9681                " Server Table-ID %d, Server Address %U",
9682                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9683       else
9684         print (vam->ofp,
9685                " Server Table-ID %d, Server Address %U",
9686                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9687     }
9688 }
9689
9690 static void vl_api_dhcp_proxy_details_t_handler_json
9691   (vl_api_dhcp_proxy_details_t * mp)
9692 {
9693   vat_main_t *vam = &vat_main;
9694   vat_json_node_t *node = NULL;
9695   u32 i, count = mp->count;
9696   struct in_addr ip4;
9697   struct in6_addr ip6;
9698   vl_api_dhcp_server_t *s;
9699
9700   if (VAT_JSON_ARRAY != vam->json_tree.type)
9701     {
9702       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9703       vat_json_init_array (&vam->json_tree);
9704     }
9705   node = vat_json_array_add (&vam->json_tree);
9706
9707   vat_json_init_object (node);
9708   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9709   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9710                              sizeof (mp->vss_type));
9711   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9712                                    mp->vss_vpn_ascii_id);
9713   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9714   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9715
9716   if (mp->is_ipv6)
9717     {
9718       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9719       vat_json_object_add_ip6 (node, "src_address", ip6);
9720     }
9721   else
9722     {
9723       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9724       vat_json_object_add_ip4 (node, "src_address", ip4);
9725     }
9726
9727   for (i = 0; i < count; i++)
9728     {
9729       s = &mp->servers[i];
9730
9731       vat_json_object_add_uint (node, "server-table-id",
9732                                 ntohl (s->server_vrf_id));
9733
9734       if (mp->is_ipv6)
9735         {
9736           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9737           vat_json_object_add_ip4 (node, "src_address", ip4);
9738         }
9739       else
9740         {
9741           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9742           vat_json_object_add_ip6 (node, "server_address", ip6);
9743         }
9744     }
9745 }
9746
9747 static int
9748 api_dhcp_proxy_dump (vat_main_t * vam)
9749 {
9750   unformat_input_t *i = vam->input;
9751   vl_api_control_ping_t *mp_ping;
9752   vl_api_dhcp_proxy_dump_t *mp;
9753   u8 is_ipv6 = 0;
9754   int ret;
9755
9756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (i, "ipv6"))
9759         is_ipv6 = 1;
9760       else
9761         {
9762           clib_warning ("parse error '%U'", format_unformat_error, i);
9763           return -99;
9764         }
9765     }
9766
9767   M (DHCP_PROXY_DUMP, mp);
9768
9769   mp->is_ip6 = is_ipv6;
9770   S (mp);
9771
9772   /* Use a control ping for synchronization */
9773   MPING (CONTROL_PING, mp_ping);
9774   S (mp_ping);
9775
9776   W (ret);
9777   return ret;
9778 }
9779
9780 static int
9781 api_dhcp_proxy_set_vss (vat_main_t * vam)
9782 {
9783   unformat_input_t *i = vam->input;
9784   vl_api_dhcp_proxy_set_vss_t *mp;
9785   u8 is_ipv6 = 0;
9786   u8 is_add = 1;
9787   u32 tbl_id = ~0;
9788   u8 vss_type = VSS_TYPE_DEFAULT;
9789   u8 *vpn_ascii_id = 0;
9790   u32 oui = 0;
9791   u32 fib_id = 0;
9792   int ret;
9793
9794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9795     {
9796       if (unformat (i, "tbl_id %d", &tbl_id))
9797         ;
9798       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9799         vss_type = VSS_TYPE_ASCII;
9800       else if (unformat (i, "fib_id %d", &fib_id))
9801         vss_type = VSS_TYPE_VPN_ID;
9802       else if (unformat (i, "oui %d", &oui))
9803         vss_type = VSS_TYPE_VPN_ID;
9804       else if (unformat (i, "ipv6"))
9805         is_ipv6 = 1;
9806       else if (unformat (i, "del"))
9807         is_add = 0;
9808       else
9809         break;
9810     }
9811
9812   if (tbl_id == ~0)
9813     {
9814       errmsg ("missing tbl_id ");
9815       vec_free (vpn_ascii_id);
9816       return -99;
9817     }
9818
9819   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9820     {
9821       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9822       vec_free (vpn_ascii_id);
9823       return -99;
9824     }
9825
9826   M (DHCP_PROXY_SET_VSS, mp);
9827   mp->tbl_id = ntohl (tbl_id);
9828   mp->vss_type = vss_type;
9829   if (vpn_ascii_id)
9830     {
9831       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9832       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9833     }
9834   mp->vpn_index = ntohl (fib_id);
9835   mp->oui = ntohl (oui);
9836   mp->is_ipv6 = is_ipv6;
9837   mp->is_add = is_add;
9838
9839   S (mp);
9840   W (ret);
9841
9842   vec_free (vpn_ascii_id);
9843   return ret;
9844 }
9845
9846 static int
9847 api_dhcp_client_config (vat_main_t * vam)
9848 {
9849   unformat_input_t *i = vam->input;
9850   vl_api_dhcp_client_config_t *mp;
9851   u32 sw_if_index;
9852   u8 sw_if_index_set = 0;
9853   u8 is_add = 1;
9854   u8 *hostname = 0;
9855   u8 disable_event = 0;
9856   int ret;
9857
9858   /* Parse args required to build the message */
9859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9860     {
9861       if (unformat (i, "del"))
9862         is_add = 0;
9863       else
9864         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9865         sw_if_index_set = 1;
9866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9867         sw_if_index_set = 1;
9868       else if (unformat (i, "hostname %s", &hostname))
9869         ;
9870       else if (unformat (i, "disable_event"))
9871         disable_event = 1;
9872       else
9873         break;
9874     }
9875
9876   if (sw_if_index_set == 0)
9877     {
9878       errmsg ("missing interface name or sw_if_index");
9879       return -99;
9880     }
9881
9882   if (vec_len (hostname) > 63)
9883     {
9884       errmsg ("hostname too long");
9885     }
9886   vec_add1 (hostname, 0);
9887
9888   /* Construct the API message */
9889   M (DHCP_CLIENT_CONFIG, mp);
9890
9891   mp->is_add = is_add;
9892   mp->client.sw_if_index = htonl (sw_if_index);
9893   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9894   vec_free (hostname);
9895   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9896   mp->client.pid = htonl (getpid ());
9897
9898   /* send it... */
9899   S (mp);
9900
9901   /* Wait for a reply, return good/bad news  */
9902   W (ret);
9903   return ret;
9904 }
9905
9906 static int
9907 api_set_ip_flow_hash (vat_main_t * vam)
9908 {
9909   unformat_input_t *i = vam->input;
9910   vl_api_set_ip_flow_hash_t *mp;
9911   u32 vrf_id = 0;
9912   u8 is_ipv6 = 0;
9913   u8 vrf_id_set = 0;
9914   u8 src = 0;
9915   u8 dst = 0;
9916   u8 sport = 0;
9917   u8 dport = 0;
9918   u8 proto = 0;
9919   u8 reverse = 0;
9920   int ret;
9921
9922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9923     {
9924       if (unformat (i, "vrf %d", &vrf_id))
9925         vrf_id_set = 1;
9926       else if (unformat (i, "ipv6"))
9927         is_ipv6 = 1;
9928       else if (unformat (i, "src"))
9929         src = 1;
9930       else if (unformat (i, "dst"))
9931         dst = 1;
9932       else if (unformat (i, "sport"))
9933         sport = 1;
9934       else if (unformat (i, "dport"))
9935         dport = 1;
9936       else if (unformat (i, "proto"))
9937         proto = 1;
9938       else if (unformat (i, "reverse"))
9939         reverse = 1;
9940
9941       else
9942         {
9943           clib_warning ("parse error '%U'", format_unformat_error, i);
9944           return -99;
9945         }
9946     }
9947
9948   if (vrf_id_set == 0)
9949     {
9950       errmsg ("missing vrf id");
9951       return -99;
9952     }
9953
9954   M (SET_IP_FLOW_HASH, mp);
9955   mp->src = src;
9956   mp->dst = dst;
9957   mp->sport = sport;
9958   mp->dport = dport;
9959   mp->proto = proto;
9960   mp->reverse = reverse;
9961   mp->vrf_id = ntohl (vrf_id);
9962   mp->is_ipv6 = is_ipv6;
9963
9964   S (mp);
9965   W (ret);
9966   return ret;
9967 }
9968
9969 static int
9970 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9971 {
9972   unformat_input_t *i = vam->input;
9973   vl_api_sw_interface_ip6_enable_disable_t *mp;
9974   u32 sw_if_index;
9975   u8 sw_if_index_set = 0;
9976   u8 enable = 0;
9977   int ret;
9978
9979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9980     {
9981       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9982         sw_if_index_set = 1;
9983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9984         sw_if_index_set = 1;
9985       else if (unformat (i, "enable"))
9986         enable = 1;
9987       else if (unformat (i, "disable"))
9988         enable = 0;
9989       else
9990         {
9991           clib_warning ("parse error '%U'", format_unformat_error, i);
9992           return -99;
9993         }
9994     }
9995
9996   if (sw_if_index_set == 0)
9997     {
9998       errmsg ("missing interface name or sw_if_index");
9999       return -99;
10000     }
10001
10002   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10003
10004   mp->sw_if_index = ntohl (sw_if_index);
10005   mp->enable = enable;
10006
10007   S (mp);
10008   W (ret);
10009   return ret;
10010 }
10011
10012 static int
10013 api_ip6nd_proxy_add_del (vat_main_t * vam)
10014 {
10015   unformat_input_t *i = vam->input;
10016   vl_api_ip6nd_proxy_add_del_t *mp;
10017   u32 sw_if_index = ~0;
10018   u8 v6_address_set = 0;
10019   vl_api_ip6_address_t v6address;
10020   u8 is_del = 0;
10021   int ret;
10022
10023   /* Parse args required to build the message */
10024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10025     {
10026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10027         ;
10028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10029         ;
10030       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10031         v6_address_set = 1;
10032       if (unformat (i, "del"))
10033         is_del = 1;
10034       else
10035         {
10036           clib_warning ("parse error '%U'", format_unformat_error, i);
10037           return -99;
10038         }
10039     }
10040
10041   if (sw_if_index == ~0)
10042     {
10043       errmsg ("missing interface name or sw_if_index");
10044       return -99;
10045     }
10046   if (!v6_address_set)
10047     {
10048       errmsg ("no address set");
10049       return -99;
10050     }
10051
10052   /* Construct the API message */
10053   M (IP6ND_PROXY_ADD_DEL, mp);
10054
10055   mp->is_del = is_del;
10056   mp->sw_if_index = ntohl (sw_if_index);
10057   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10058
10059   /* send it... */
10060   S (mp);
10061
10062   /* Wait for a reply, return good/bad news  */
10063   W (ret);
10064   return ret;
10065 }
10066
10067 static int
10068 api_ip6nd_proxy_dump (vat_main_t * vam)
10069 {
10070   vl_api_ip6nd_proxy_dump_t *mp;
10071   vl_api_control_ping_t *mp_ping;
10072   int ret;
10073
10074   M (IP6ND_PROXY_DUMP, mp);
10075
10076   S (mp);
10077
10078   /* Use a control ping for synchronization */
10079   MPING (CONTROL_PING, mp_ping);
10080   S (mp_ping);
10081
10082   W (ret);
10083   return ret;
10084 }
10085
10086 static void vl_api_ip6nd_proxy_details_t_handler
10087   (vl_api_ip6nd_proxy_details_t * mp)
10088 {
10089   vat_main_t *vam = &vat_main;
10090
10091   print (vam->ofp, "host %U sw_if_index %d",
10092          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10093 }
10094
10095 static void vl_api_ip6nd_proxy_details_t_handler_json
10096   (vl_api_ip6nd_proxy_details_t * mp)
10097 {
10098   vat_main_t *vam = &vat_main;
10099   struct in6_addr ip6;
10100   vat_json_node_t *node = NULL;
10101
10102   if (VAT_JSON_ARRAY != vam->json_tree.type)
10103     {
10104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10105       vat_json_init_array (&vam->json_tree);
10106     }
10107   node = vat_json_array_add (&vam->json_tree);
10108
10109   vat_json_init_object (node);
10110   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10111
10112   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10113   vat_json_object_add_ip6 (node, "host", ip6);
10114 }
10115
10116 static int
10117 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10118 {
10119   unformat_input_t *i = vam->input;
10120   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10121   u32 sw_if_index;
10122   u8 sw_if_index_set = 0;
10123   u8 v6_address_set = 0;
10124   vl_api_prefix_t pfx;
10125   u8 use_default = 0;
10126   u8 no_advertise = 0;
10127   u8 off_link = 0;
10128   u8 no_autoconfig = 0;
10129   u8 no_onlink = 0;
10130   u8 is_no = 0;
10131   u32 val_lifetime = 0;
10132   u32 pref_lifetime = 0;
10133   int ret;
10134
10135   /* Parse args required to build the message */
10136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10137     {
10138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10139         sw_if_index_set = 1;
10140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10141         sw_if_index_set = 1;
10142       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10143         v6_address_set = 1;
10144       else if (unformat (i, "val_life %d", &val_lifetime))
10145         ;
10146       else if (unformat (i, "pref_life %d", &pref_lifetime))
10147         ;
10148       else if (unformat (i, "def"))
10149         use_default = 1;
10150       else if (unformat (i, "noadv"))
10151         no_advertise = 1;
10152       else if (unformat (i, "offl"))
10153         off_link = 1;
10154       else if (unformat (i, "noauto"))
10155         no_autoconfig = 1;
10156       else if (unformat (i, "nolink"))
10157         no_onlink = 1;
10158       else if (unformat (i, "isno"))
10159         is_no = 1;
10160       else
10161         {
10162           clib_warning ("parse error '%U'", format_unformat_error, i);
10163           return -99;
10164         }
10165     }
10166
10167   if (sw_if_index_set == 0)
10168     {
10169       errmsg ("missing interface name or sw_if_index");
10170       return -99;
10171     }
10172   if (!v6_address_set)
10173     {
10174       errmsg ("no address set");
10175       return -99;
10176     }
10177
10178   /* Construct the API message */
10179   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10180
10181   mp->sw_if_index = ntohl (sw_if_index);
10182   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10183   mp->use_default = use_default;
10184   mp->no_advertise = no_advertise;
10185   mp->off_link = off_link;
10186   mp->no_autoconfig = no_autoconfig;
10187   mp->no_onlink = no_onlink;
10188   mp->is_no = is_no;
10189   mp->val_lifetime = ntohl (val_lifetime);
10190   mp->pref_lifetime = ntohl (pref_lifetime);
10191
10192   /* send it... */
10193   S (mp);
10194
10195   /* Wait for a reply, return good/bad news  */
10196   W (ret);
10197   return ret;
10198 }
10199
10200 static int
10201 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10202 {
10203   unformat_input_t *i = vam->input;
10204   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10205   u32 sw_if_index;
10206   u8 sw_if_index_set = 0;
10207   u8 suppress = 0;
10208   u8 managed = 0;
10209   u8 other = 0;
10210   u8 ll_option = 0;
10211   u8 send_unicast = 0;
10212   u8 cease = 0;
10213   u8 is_no = 0;
10214   u8 default_router = 0;
10215   u32 max_interval = 0;
10216   u32 min_interval = 0;
10217   u32 lifetime = 0;
10218   u32 initial_count = 0;
10219   u32 initial_interval = 0;
10220   int ret;
10221
10222
10223   /* Parse args required to build the message */
10224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10225     {
10226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10227         sw_if_index_set = 1;
10228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10229         sw_if_index_set = 1;
10230       else if (unformat (i, "maxint %d", &max_interval))
10231         ;
10232       else if (unformat (i, "minint %d", &min_interval))
10233         ;
10234       else if (unformat (i, "life %d", &lifetime))
10235         ;
10236       else if (unformat (i, "count %d", &initial_count))
10237         ;
10238       else if (unformat (i, "interval %d", &initial_interval))
10239         ;
10240       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10241         suppress = 1;
10242       else if (unformat (i, "managed"))
10243         managed = 1;
10244       else if (unformat (i, "other"))
10245         other = 1;
10246       else if (unformat (i, "ll"))
10247         ll_option = 1;
10248       else if (unformat (i, "send"))
10249         send_unicast = 1;
10250       else if (unformat (i, "cease"))
10251         cease = 1;
10252       else if (unformat (i, "isno"))
10253         is_no = 1;
10254       else if (unformat (i, "def"))
10255         default_router = 1;
10256       else
10257         {
10258           clib_warning ("parse error '%U'", format_unformat_error, i);
10259           return -99;
10260         }
10261     }
10262
10263   if (sw_if_index_set == 0)
10264     {
10265       errmsg ("missing interface name or sw_if_index");
10266       return -99;
10267     }
10268
10269   /* Construct the API message */
10270   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10271
10272   mp->sw_if_index = ntohl (sw_if_index);
10273   mp->max_interval = ntohl (max_interval);
10274   mp->min_interval = ntohl (min_interval);
10275   mp->lifetime = ntohl (lifetime);
10276   mp->initial_count = ntohl (initial_count);
10277   mp->initial_interval = ntohl (initial_interval);
10278   mp->suppress = suppress;
10279   mp->managed = managed;
10280   mp->other = other;
10281   mp->ll_option = ll_option;
10282   mp->send_unicast = send_unicast;
10283   mp->cease = cease;
10284   mp->is_no = is_no;
10285   mp->default_router = default_router;
10286
10287   /* send it... */
10288   S (mp);
10289
10290   /* Wait for a reply, return good/bad news  */
10291   W (ret);
10292   return ret;
10293 }
10294
10295 static int
10296 api_set_arp_neighbor_limit (vat_main_t * vam)
10297 {
10298   unformat_input_t *i = vam->input;
10299   vl_api_set_arp_neighbor_limit_t *mp;
10300   u32 arp_nbr_limit;
10301   u8 limit_set = 0;
10302   u8 is_ipv6 = 0;
10303   int ret;
10304
10305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10306     {
10307       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10308         limit_set = 1;
10309       else if (unformat (i, "ipv6"))
10310         is_ipv6 = 1;
10311       else
10312         {
10313           clib_warning ("parse error '%U'", format_unformat_error, i);
10314           return -99;
10315         }
10316     }
10317
10318   if (limit_set == 0)
10319     {
10320       errmsg ("missing limit value");
10321       return -99;
10322     }
10323
10324   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10325
10326   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10327   mp->is_ipv6 = is_ipv6;
10328
10329   S (mp);
10330   W (ret);
10331   return ret;
10332 }
10333
10334 static int
10335 api_l2_patch_add_del (vat_main_t * vam)
10336 {
10337   unformat_input_t *i = vam->input;
10338   vl_api_l2_patch_add_del_t *mp;
10339   u32 rx_sw_if_index;
10340   u8 rx_sw_if_index_set = 0;
10341   u32 tx_sw_if_index;
10342   u8 tx_sw_if_index_set = 0;
10343   u8 is_add = 1;
10344   int ret;
10345
10346   /* Parse args required to build the message */
10347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10348     {
10349       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10350         rx_sw_if_index_set = 1;
10351       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10352         tx_sw_if_index_set = 1;
10353       else if (unformat (i, "rx"))
10354         {
10355           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10356             {
10357               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10358                             &rx_sw_if_index))
10359                 rx_sw_if_index_set = 1;
10360             }
10361           else
10362             break;
10363         }
10364       else if (unformat (i, "tx"))
10365         {
10366           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10367             {
10368               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10369                             &tx_sw_if_index))
10370                 tx_sw_if_index_set = 1;
10371             }
10372           else
10373             break;
10374         }
10375       else if (unformat (i, "del"))
10376         is_add = 0;
10377       else
10378         break;
10379     }
10380
10381   if (rx_sw_if_index_set == 0)
10382     {
10383       errmsg ("missing rx interface name or rx_sw_if_index");
10384       return -99;
10385     }
10386
10387   if (tx_sw_if_index_set == 0)
10388     {
10389       errmsg ("missing tx interface name or tx_sw_if_index");
10390       return -99;
10391     }
10392
10393   M (L2_PATCH_ADD_DEL, mp);
10394
10395   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10396   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10397   mp->is_add = is_add;
10398
10399   S (mp);
10400   W (ret);
10401   return ret;
10402 }
10403
10404 u8 is_del;
10405 u8 localsid_addr[16];
10406 u8 end_psp;
10407 u8 behavior;
10408 u32 sw_if_index;
10409 u32 vlan_index;
10410 u32 fib_table;
10411 u8 nh_addr[16];
10412
10413 static int
10414 api_sr_localsid_add_del (vat_main_t * vam)
10415 {
10416   unformat_input_t *i = vam->input;
10417   vl_api_sr_localsid_add_del_t *mp;
10418
10419   u8 is_del;
10420   ip6_address_t localsid;
10421   u8 end_psp = 0;
10422   u8 behavior = ~0;
10423   u32 sw_if_index;
10424   u32 fib_table = ~(u32) 0;
10425   ip6_address_t nh_addr6;
10426   ip4_address_t nh_addr4;
10427   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10428   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10429
10430   bool nexthop_set = 0;
10431
10432   int ret;
10433
10434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10435     {
10436       if (unformat (i, "del"))
10437         is_del = 1;
10438       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10439       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10440         nexthop_set = 1;
10441       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10442         nexthop_set = 1;
10443       else if (unformat (i, "behavior %u", &behavior));
10444       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10445       else if (unformat (i, "fib-table %u", &fib_table));
10446       else if (unformat (i, "end.psp %u", &behavior));
10447       else
10448         break;
10449     }
10450
10451   M (SR_LOCALSID_ADD_DEL, mp);
10452
10453   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10454   if (nexthop_set)
10455     {
10456       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10457       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10458     }
10459   mp->behavior = behavior;
10460   mp->sw_if_index = ntohl (sw_if_index);
10461   mp->fib_table = ntohl (fib_table);
10462   mp->end_psp = end_psp;
10463   mp->is_del = is_del;
10464
10465   S (mp);
10466   W (ret);
10467   return ret;
10468 }
10469
10470 static int
10471 api_ioam_enable (vat_main_t * vam)
10472 {
10473   unformat_input_t *input = vam->input;
10474   vl_api_ioam_enable_t *mp;
10475   u32 id = 0;
10476   int has_trace_option = 0;
10477   int has_pot_option = 0;
10478   int has_seqno_option = 0;
10479   int has_analyse_option = 0;
10480   int ret;
10481
10482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10483     {
10484       if (unformat (input, "trace"))
10485         has_trace_option = 1;
10486       else if (unformat (input, "pot"))
10487         has_pot_option = 1;
10488       else if (unformat (input, "seqno"))
10489         has_seqno_option = 1;
10490       else if (unformat (input, "analyse"))
10491         has_analyse_option = 1;
10492       else
10493         break;
10494     }
10495   M (IOAM_ENABLE, mp);
10496   mp->id = htons (id);
10497   mp->seqno = has_seqno_option;
10498   mp->analyse = has_analyse_option;
10499   mp->pot_enable = has_pot_option;
10500   mp->trace_enable = has_trace_option;
10501
10502   S (mp);
10503   W (ret);
10504   return ret;
10505 }
10506
10507
10508 static int
10509 api_ioam_disable (vat_main_t * vam)
10510 {
10511   vl_api_ioam_disable_t *mp;
10512   int ret;
10513
10514   M (IOAM_DISABLE, mp);
10515   S (mp);
10516   W (ret);
10517   return ret;
10518 }
10519
10520 #define foreach_tcp_proto_field                 \
10521 _(src_port)                                     \
10522 _(dst_port)
10523
10524 #define foreach_udp_proto_field                 \
10525 _(src_port)                                     \
10526 _(dst_port)
10527
10528 #define foreach_ip4_proto_field                 \
10529 _(src_address)                                  \
10530 _(dst_address)                                  \
10531 _(tos)                                          \
10532 _(length)                                       \
10533 _(fragment_id)                                  \
10534 _(ttl)                                          \
10535 _(protocol)                                     \
10536 _(checksum)
10537
10538 typedef struct
10539 {
10540   u16 src_port, dst_port;
10541 } tcpudp_header_t;
10542
10543 #if VPP_API_TEST_BUILTIN == 0
10544 uword
10545 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10546 {
10547   u8 **maskp = va_arg (*args, u8 **);
10548   u8 *mask = 0;
10549   u8 found_something = 0;
10550   tcp_header_t *tcp;
10551
10552 #define _(a) u8 a=0;
10553   foreach_tcp_proto_field;
10554 #undef _
10555
10556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10557     {
10558       if (0);
10559 #define _(a) else if (unformat (input, #a)) a=1;
10560       foreach_tcp_proto_field
10561 #undef _
10562         else
10563         break;
10564     }
10565
10566 #define _(a) found_something += a;
10567   foreach_tcp_proto_field;
10568 #undef _
10569
10570   if (found_something == 0)
10571     return 0;
10572
10573   vec_validate (mask, sizeof (*tcp) - 1);
10574
10575   tcp = (tcp_header_t *) mask;
10576
10577 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10578   foreach_tcp_proto_field;
10579 #undef _
10580
10581   *maskp = mask;
10582   return 1;
10583 }
10584
10585 uword
10586 unformat_udp_mask (unformat_input_t * input, va_list * args)
10587 {
10588   u8 **maskp = va_arg (*args, u8 **);
10589   u8 *mask = 0;
10590   u8 found_something = 0;
10591   udp_header_t *udp;
10592
10593 #define _(a) u8 a=0;
10594   foreach_udp_proto_field;
10595 #undef _
10596
10597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10598     {
10599       if (0);
10600 #define _(a) else if (unformat (input, #a)) a=1;
10601       foreach_udp_proto_field
10602 #undef _
10603         else
10604         break;
10605     }
10606
10607 #define _(a) found_something += a;
10608   foreach_udp_proto_field;
10609 #undef _
10610
10611   if (found_something == 0)
10612     return 0;
10613
10614   vec_validate (mask, sizeof (*udp) - 1);
10615
10616   udp = (udp_header_t *) mask;
10617
10618 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10619   foreach_udp_proto_field;
10620 #undef _
10621
10622   *maskp = mask;
10623   return 1;
10624 }
10625
10626 uword
10627 unformat_l4_mask (unformat_input_t * input, va_list * args)
10628 {
10629   u8 **maskp = va_arg (*args, u8 **);
10630   u16 src_port = 0, dst_port = 0;
10631   tcpudp_header_t *tcpudp;
10632
10633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10634     {
10635       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10636         return 1;
10637       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10638         return 1;
10639       else if (unformat (input, "src_port"))
10640         src_port = 0xFFFF;
10641       else if (unformat (input, "dst_port"))
10642         dst_port = 0xFFFF;
10643       else
10644         return 0;
10645     }
10646
10647   if (!src_port && !dst_port)
10648     return 0;
10649
10650   u8 *mask = 0;
10651   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10652
10653   tcpudp = (tcpudp_header_t *) mask;
10654   tcpudp->src_port = src_port;
10655   tcpudp->dst_port = dst_port;
10656
10657   *maskp = mask;
10658
10659   return 1;
10660 }
10661
10662 uword
10663 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10664 {
10665   u8 **maskp = va_arg (*args, u8 **);
10666   u8 *mask = 0;
10667   u8 found_something = 0;
10668   ip4_header_t *ip;
10669
10670 #define _(a) u8 a=0;
10671   foreach_ip4_proto_field;
10672 #undef _
10673   u8 version = 0;
10674   u8 hdr_length = 0;
10675
10676
10677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (input, "version"))
10680         version = 1;
10681       else if (unformat (input, "hdr_length"))
10682         hdr_length = 1;
10683       else if (unformat (input, "src"))
10684         src_address = 1;
10685       else if (unformat (input, "dst"))
10686         dst_address = 1;
10687       else if (unformat (input, "proto"))
10688         protocol = 1;
10689
10690 #define _(a) else if (unformat (input, #a)) a=1;
10691       foreach_ip4_proto_field
10692 #undef _
10693         else
10694         break;
10695     }
10696
10697 #define _(a) found_something += a;
10698   foreach_ip4_proto_field;
10699 #undef _
10700
10701   if (found_something == 0)
10702     return 0;
10703
10704   vec_validate (mask, sizeof (*ip) - 1);
10705
10706   ip = (ip4_header_t *) mask;
10707
10708 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10709   foreach_ip4_proto_field;
10710 #undef _
10711
10712   ip->ip_version_and_header_length = 0;
10713
10714   if (version)
10715     ip->ip_version_and_header_length |= 0xF0;
10716
10717   if (hdr_length)
10718     ip->ip_version_and_header_length |= 0x0F;
10719
10720   *maskp = mask;
10721   return 1;
10722 }
10723
10724 #define foreach_ip6_proto_field                 \
10725 _(src_address)                                  \
10726 _(dst_address)                                  \
10727 _(payload_length)                               \
10728 _(hop_limit)                                    \
10729 _(protocol)
10730
10731 uword
10732 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10733 {
10734   u8 **maskp = va_arg (*args, u8 **);
10735   u8 *mask = 0;
10736   u8 found_something = 0;
10737   ip6_header_t *ip;
10738   u32 ip_version_traffic_class_and_flow_label;
10739
10740 #define _(a) u8 a=0;
10741   foreach_ip6_proto_field;
10742 #undef _
10743   u8 version = 0;
10744   u8 traffic_class = 0;
10745   u8 flow_label = 0;
10746
10747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10748     {
10749       if (unformat (input, "version"))
10750         version = 1;
10751       else if (unformat (input, "traffic-class"))
10752         traffic_class = 1;
10753       else if (unformat (input, "flow-label"))
10754         flow_label = 1;
10755       else if (unformat (input, "src"))
10756         src_address = 1;
10757       else if (unformat (input, "dst"))
10758         dst_address = 1;
10759       else if (unformat (input, "proto"))
10760         protocol = 1;
10761
10762 #define _(a) else if (unformat (input, #a)) a=1;
10763       foreach_ip6_proto_field
10764 #undef _
10765         else
10766         break;
10767     }
10768
10769 #define _(a) found_something += a;
10770   foreach_ip6_proto_field;
10771 #undef _
10772
10773   if (found_something == 0)
10774     return 0;
10775
10776   vec_validate (mask, sizeof (*ip) - 1);
10777
10778   ip = (ip6_header_t *) mask;
10779
10780 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10781   foreach_ip6_proto_field;
10782 #undef _
10783
10784   ip_version_traffic_class_and_flow_label = 0;
10785
10786   if (version)
10787     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10788
10789   if (traffic_class)
10790     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10791
10792   if (flow_label)
10793     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10794
10795   ip->ip_version_traffic_class_and_flow_label =
10796     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10797
10798   *maskp = mask;
10799   return 1;
10800 }
10801
10802 uword
10803 unformat_l3_mask (unformat_input_t * input, va_list * args)
10804 {
10805   u8 **maskp = va_arg (*args, u8 **);
10806
10807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10808     {
10809       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10810         return 1;
10811       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10812         return 1;
10813       else
10814         break;
10815     }
10816   return 0;
10817 }
10818
10819 uword
10820 unformat_l2_mask (unformat_input_t * input, va_list * args)
10821 {
10822   u8 **maskp = va_arg (*args, u8 **);
10823   u8 *mask = 0;
10824   u8 src = 0;
10825   u8 dst = 0;
10826   u8 proto = 0;
10827   u8 tag1 = 0;
10828   u8 tag2 = 0;
10829   u8 ignore_tag1 = 0;
10830   u8 ignore_tag2 = 0;
10831   u8 cos1 = 0;
10832   u8 cos2 = 0;
10833   u8 dot1q = 0;
10834   u8 dot1ad = 0;
10835   int len = 14;
10836
10837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10838     {
10839       if (unformat (input, "src"))
10840         src = 1;
10841       else if (unformat (input, "dst"))
10842         dst = 1;
10843       else if (unformat (input, "proto"))
10844         proto = 1;
10845       else if (unformat (input, "tag1"))
10846         tag1 = 1;
10847       else if (unformat (input, "tag2"))
10848         tag2 = 1;
10849       else if (unformat (input, "ignore-tag1"))
10850         ignore_tag1 = 1;
10851       else if (unformat (input, "ignore-tag2"))
10852         ignore_tag2 = 1;
10853       else if (unformat (input, "cos1"))
10854         cos1 = 1;
10855       else if (unformat (input, "cos2"))
10856         cos2 = 1;
10857       else if (unformat (input, "dot1q"))
10858         dot1q = 1;
10859       else if (unformat (input, "dot1ad"))
10860         dot1ad = 1;
10861       else
10862         break;
10863     }
10864   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10865        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10866     return 0;
10867
10868   if (tag1 || ignore_tag1 || cos1 || dot1q)
10869     len = 18;
10870   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10871     len = 22;
10872
10873   vec_validate (mask, len - 1);
10874
10875   if (dst)
10876     clib_memset (mask, 0xff, 6);
10877
10878   if (src)
10879     clib_memset (mask + 6, 0xff, 6);
10880
10881   if (tag2 || dot1ad)
10882     {
10883       /* inner vlan tag */
10884       if (tag2)
10885         {
10886           mask[19] = 0xff;
10887           mask[18] = 0x0f;
10888         }
10889       if (cos2)
10890         mask[18] |= 0xe0;
10891       if (proto)
10892         mask[21] = mask[20] = 0xff;
10893       if (tag1)
10894         {
10895           mask[15] = 0xff;
10896           mask[14] = 0x0f;
10897         }
10898       if (cos1)
10899         mask[14] |= 0xe0;
10900       *maskp = mask;
10901       return 1;
10902     }
10903   if (tag1 | dot1q)
10904     {
10905       if (tag1)
10906         {
10907           mask[15] = 0xff;
10908           mask[14] = 0x0f;
10909         }
10910       if (cos1)
10911         mask[14] |= 0xe0;
10912       if (proto)
10913         mask[16] = mask[17] = 0xff;
10914
10915       *maskp = mask;
10916       return 1;
10917     }
10918   if (cos2)
10919     mask[18] |= 0xe0;
10920   if (cos1)
10921     mask[14] |= 0xe0;
10922   if (proto)
10923     mask[12] = mask[13] = 0xff;
10924
10925   *maskp = mask;
10926   return 1;
10927 }
10928
10929 uword
10930 unformat_classify_mask (unformat_input_t * input, va_list * args)
10931 {
10932   u8 **maskp = va_arg (*args, u8 **);
10933   u32 *skipp = va_arg (*args, u32 *);
10934   u32 *matchp = va_arg (*args, u32 *);
10935   u32 match;
10936   u8 *mask = 0;
10937   u8 *l2 = 0;
10938   u8 *l3 = 0;
10939   u8 *l4 = 0;
10940   int i;
10941
10942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10943     {
10944       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10945         ;
10946       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10947         ;
10948       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10949         ;
10950       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10951         ;
10952       else
10953         break;
10954     }
10955
10956   if (l4 && !l3)
10957     {
10958       vec_free (mask);
10959       vec_free (l2);
10960       vec_free (l4);
10961       return 0;
10962     }
10963
10964   if (mask || l2 || l3 || l4)
10965     {
10966       if (l2 || l3 || l4)
10967         {
10968           /* "With a free Ethernet header in every package" */
10969           if (l2 == 0)
10970             vec_validate (l2, 13);
10971           mask = l2;
10972           if (vec_len (l3))
10973             {
10974               vec_append (mask, l3);
10975               vec_free (l3);
10976             }
10977           if (vec_len (l4))
10978             {
10979               vec_append (mask, l4);
10980               vec_free (l4);
10981             }
10982         }
10983
10984       /* Scan forward looking for the first significant mask octet */
10985       for (i = 0; i < vec_len (mask); i++)
10986         if (mask[i])
10987           break;
10988
10989       /* compute (skip, match) params */
10990       *skipp = i / sizeof (u32x4);
10991       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10992
10993       /* Pad mask to an even multiple of the vector size */
10994       while (vec_len (mask) % sizeof (u32x4))
10995         vec_add1 (mask, 0);
10996
10997       match = vec_len (mask) / sizeof (u32x4);
10998
10999       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11000         {
11001           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11002           if (*tmp || *(tmp + 1))
11003             break;
11004           match--;
11005         }
11006       if (match == 0)
11007         clib_warning ("BUG: match 0");
11008
11009       _vec_len (mask) = match * sizeof (u32x4);
11010
11011       *matchp = match;
11012       *maskp = mask;
11013
11014       return 1;
11015     }
11016
11017   return 0;
11018 }
11019 #endif /* VPP_API_TEST_BUILTIN */
11020
11021 #define foreach_l2_next                         \
11022 _(drop, DROP)                                   \
11023 _(ethernet, ETHERNET_INPUT)                     \
11024 _(ip4, IP4_INPUT)                               \
11025 _(ip6, IP6_INPUT)
11026
11027 uword
11028 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11029 {
11030   u32 *miss_next_indexp = va_arg (*args, u32 *);
11031   u32 next_index = 0;
11032   u32 tmp;
11033
11034 #define _(n,N) \
11035   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11036   foreach_l2_next;
11037 #undef _
11038
11039   if (unformat (input, "%d", &tmp))
11040     {
11041       next_index = tmp;
11042       goto out;
11043     }
11044
11045   return 0;
11046
11047 out:
11048   *miss_next_indexp = next_index;
11049   return 1;
11050 }
11051
11052 #define foreach_ip_next                         \
11053 _(drop, DROP)                                   \
11054 _(local, LOCAL)                                 \
11055 _(rewrite, REWRITE)
11056
11057 uword
11058 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11059 {
11060   u32 *miss_next_indexp = va_arg (*args, u32 *);
11061   u32 next_index = 0;
11062   u32 tmp;
11063
11064 #define _(n,N) \
11065   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11066   foreach_ip_next;
11067 #undef _
11068
11069   if (unformat (input, "%d", &tmp))
11070     {
11071       next_index = tmp;
11072       goto out;
11073     }
11074
11075   return 0;
11076
11077 out:
11078   *miss_next_indexp = next_index;
11079   return 1;
11080 }
11081
11082 #define foreach_acl_next                        \
11083 _(deny, DENY)
11084
11085 uword
11086 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11087 {
11088   u32 *miss_next_indexp = va_arg (*args, u32 *);
11089   u32 next_index = 0;
11090   u32 tmp;
11091
11092 #define _(n,N) \
11093   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11094   foreach_acl_next;
11095 #undef _
11096
11097   if (unformat (input, "permit"))
11098     {
11099       next_index = ~0;
11100       goto out;
11101     }
11102   else if (unformat (input, "%d", &tmp))
11103     {
11104       next_index = tmp;
11105       goto out;
11106     }
11107
11108   return 0;
11109
11110 out:
11111   *miss_next_indexp = next_index;
11112   return 1;
11113 }
11114
11115 uword
11116 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11117 {
11118   u32 *r = va_arg (*args, u32 *);
11119
11120   if (unformat (input, "conform-color"))
11121     *r = POLICE_CONFORM;
11122   else if (unformat (input, "exceed-color"))
11123     *r = POLICE_EXCEED;
11124   else
11125     return 0;
11126
11127   return 1;
11128 }
11129
11130 static int
11131 api_classify_add_del_table (vat_main_t * vam)
11132 {
11133   unformat_input_t *i = vam->input;
11134   vl_api_classify_add_del_table_t *mp;
11135
11136   u32 nbuckets = 2;
11137   u32 skip = ~0;
11138   u32 match = ~0;
11139   int is_add = 1;
11140   int del_chain = 0;
11141   u32 table_index = ~0;
11142   u32 next_table_index = ~0;
11143   u32 miss_next_index = ~0;
11144   u32 memory_size = 32 << 20;
11145   u8 *mask = 0;
11146   u32 current_data_flag = 0;
11147   int current_data_offset = 0;
11148   int ret;
11149
11150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11151     {
11152       if (unformat (i, "del"))
11153         is_add = 0;
11154       else if (unformat (i, "del-chain"))
11155         {
11156           is_add = 0;
11157           del_chain = 1;
11158         }
11159       else if (unformat (i, "buckets %d", &nbuckets))
11160         ;
11161       else if (unformat (i, "memory_size %d", &memory_size))
11162         ;
11163       else if (unformat (i, "skip %d", &skip))
11164         ;
11165       else if (unformat (i, "match %d", &match))
11166         ;
11167       else if (unformat (i, "table %d", &table_index))
11168         ;
11169       else if (unformat (i, "mask %U", unformat_classify_mask,
11170                          &mask, &skip, &match))
11171         ;
11172       else if (unformat (i, "next-table %d", &next_table_index))
11173         ;
11174       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11175                          &miss_next_index))
11176         ;
11177       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11178                          &miss_next_index))
11179         ;
11180       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11181                          &miss_next_index))
11182         ;
11183       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11184         ;
11185       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11186         ;
11187       else
11188         break;
11189     }
11190
11191   if (is_add && mask == 0)
11192     {
11193       errmsg ("Mask required");
11194       return -99;
11195     }
11196
11197   if (is_add && skip == ~0)
11198     {
11199       errmsg ("skip count required");
11200       return -99;
11201     }
11202
11203   if (is_add && match == ~0)
11204     {
11205       errmsg ("match count required");
11206       return -99;
11207     }
11208
11209   if (!is_add && table_index == ~0)
11210     {
11211       errmsg ("table index required for delete");
11212       return -99;
11213     }
11214
11215   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11216
11217   mp->is_add = is_add;
11218   mp->del_chain = del_chain;
11219   mp->table_index = ntohl (table_index);
11220   mp->nbuckets = ntohl (nbuckets);
11221   mp->memory_size = ntohl (memory_size);
11222   mp->skip_n_vectors = ntohl (skip);
11223   mp->match_n_vectors = ntohl (match);
11224   mp->next_table_index = ntohl (next_table_index);
11225   mp->miss_next_index = ntohl (miss_next_index);
11226   mp->current_data_flag = ntohl (current_data_flag);
11227   mp->current_data_offset = ntohl (current_data_offset);
11228   mp->mask_len = ntohl (vec_len (mask));
11229   clib_memcpy (mp->mask, mask, vec_len (mask));
11230
11231   vec_free (mask);
11232
11233   S (mp);
11234   W (ret);
11235   return ret;
11236 }
11237
11238 #if VPP_API_TEST_BUILTIN == 0
11239 uword
11240 unformat_l4_match (unformat_input_t * input, va_list * args)
11241 {
11242   u8 **matchp = va_arg (*args, u8 **);
11243
11244   u8 *proto_header = 0;
11245   int src_port = 0;
11246   int dst_port = 0;
11247
11248   tcpudp_header_t h;
11249
11250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11251     {
11252       if (unformat (input, "src_port %d", &src_port))
11253         ;
11254       else if (unformat (input, "dst_port %d", &dst_port))
11255         ;
11256       else
11257         return 0;
11258     }
11259
11260   h.src_port = clib_host_to_net_u16 (src_port);
11261   h.dst_port = clib_host_to_net_u16 (dst_port);
11262   vec_validate (proto_header, sizeof (h) - 1);
11263   memcpy (proto_header, &h, sizeof (h));
11264
11265   *matchp = proto_header;
11266
11267   return 1;
11268 }
11269
11270 uword
11271 unformat_ip4_match (unformat_input_t * input, va_list * args)
11272 {
11273   u8 **matchp = va_arg (*args, u8 **);
11274   u8 *match = 0;
11275   ip4_header_t *ip;
11276   int version = 0;
11277   u32 version_val;
11278   int hdr_length = 0;
11279   u32 hdr_length_val;
11280   int src = 0, dst = 0;
11281   ip4_address_t src_val, dst_val;
11282   int proto = 0;
11283   u32 proto_val;
11284   int tos = 0;
11285   u32 tos_val;
11286   int length = 0;
11287   u32 length_val;
11288   int fragment_id = 0;
11289   u32 fragment_id_val;
11290   int ttl = 0;
11291   int ttl_val;
11292   int checksum = 0;
11293   u32 checksum_val;
11294
11295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11296     {
11297       if (unformat (input, "version %d", &version_val))
11298         version = 1;
11299       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11300         hdr_length = 1;
11301       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11302         src = 1;
11303       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11304         dst = 1;
11305       else if (unformat (input, "proto %d", &proto_val))
11306         proto = 1;
11307       else if (unformat (input, "tos %d", &tos_val))
11308         tos = 1;
11309       else if (unformat (input, "length %d", &length_val))
11310         length = 1;
11311       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11312         fragment_id = 1;
11313       else if (unformat (input, "ttl %d", &ttl_val))
11314         ttl = 1;
11315       else if (unformat (input, "checksum %d", &checksum_val))
11316         checksum = 1;
11317       else
11318         break;
11319     }
11320
11321   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11322       + ttl + checksum == 0)
11323     return 0;
11324
11325   /*
11326    * Aligned because we use the real comparison functions
11327    */
11328   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11329
11330   ip = (ip4_header_t *) match;
11331
11332   /* These are realistically matched in practice */
11333   if (src)
11334     ip->src_address.as_u32 = src_val.as_u32;
11335
11336   if (dst)
11337     ip->dst_address.as_u32 = dst_val.as_u32;
11338
11339   if (proto)
11340     ip->protocol = proto_val;
11341
11342
11343   /* These are not, but they're included for completeness */
11344   if (version)
11345     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11346
11347   if (hdr_length)
11348     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11349
11350   if (tos)
11351     ip->tos = tos_val;
11352
11353   if (length)
11354     ip->length = clib_host_to_net_u16 (length_val);
11355
11356   if (ttl)
11357     ip->ttl = ttl_val;
11358
11359   if (checksum)
11360     ip->checksum = clib_host_to_net_u16 (checksum_val);
11361
11362   *matchp = match;
11363   return 1;
11364 }
11365
11366 uword
11367 unformat_ip6_match (unformat_input_t * input, va_list * args)
11368 {
11369   u8 **matchp = va_arg (*args, u8 **);
11370   u8 *match = 0;
11371   ip6_header_t *ip;
11372   int version = 0;
11373   u32 version_val;
11374   u8 traffic_class = 0;
11375   u32 traffic_class_val = 0;
11376   u8 flow_label = 0;
11377   u8 flow_label_val;
11378   int src = 0, dst = 0;
11379   ip6_address_t src_val, dst_val;
11380   int proto = 0;
11381   u32 proto_val;
11382   int payload_length = 0;
11383   u32 payload_length_val;
11384   int hop_limit = 0;
11385   int hop_limit_val;
11386   u32 ip_version_traffic_class_and_flow_label;
11387
11388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11389     {
11390       if (unformat (input, "version %d", &version_val))
11391         version = 1;
11392       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11393         traffic_class = 1;
11394       else if (unformat (input, "flow_label %d", &flow_label_val))
11395         flow_label = 1;
11396       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11397         src = 1;
11398       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11399         dst = 1;
11400       else if (unformat (input, "proto %d", &proto_val))
11401         proto = 1;
11402       else if (unformat (input, "payload_length %d", &payload_length_val))
11403         payload_length = 1;
11404       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11405         hop_limit = 1;
11406       else
11407         break;
11408     }
11409
11410   if (version + traffic_class + flow_label + src + dst + proto +
11411       payload_length + hop_limit == 0)
11412     return 0;
11413
11414   /*
11415    * Aligned because we use the real comparison functions
11416    */
11417   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11418
11419   ip = (ip6_header_t *) match;
11420
11421   if (src)
11422     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11423
11424   if (dst)
11425     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11426
11427   if (proto)
11428     ip->protocol = proto_val;
11429
11430   ip_version_traffic_class_and_flow_label = 0;
11431
11432   if (version)
11433     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11434
11435   if (traffic_class)
11436     ip_version_traffic_class_and_flow_label |=
11437       (traffic_class_val & 0xFF) << 20;
11438
11439   if (flow_label)
11440     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11441
11442   ip->ip_version_traffic_class_and_flow_label =
11443     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11444
11445   if (payload_length)
11446     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11447
11448   if (hop_limit)
11449     ip->hop_limit = hop_limit_val;
11450
11451   *matchp = match;
11452   return 1;
11453 }
11454
11455 uword
11456 unformat_l3_match (unformat_input_t * input, va_list * args)
11457 {
11458   u8 **matchp = va_arg (*args, u8 **);
11459
11460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11461     {
11462       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11463         return 1;
11464       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11465         return 1;
11466       else
11467         break;
11468     }
11469   return 0;
11470 }
11471
11472 uword
11473 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11474 {
11475   u8 *tagp = va_arg (*args, u8 *);
11476   u32 tag;
11477
11478   if (unformat (input, "%d", &tag))
11479     {
11480       tagp[0] = (tag >> 8) & 0x0F;
11481       tagp[1] = tag & 0xFF;
11482       return 1;
11483     }
11484
11485   return 0;
11486 }
11487
11488 uword
11489 unformat_l2_match (unformat_input_t * input, va_list * args)
11490 {
11491   u8 **matchp = va_arg (*args, u8 **);
11492   u8 *match = 0;
11493   u8 src = 0;
11494   u8 src_val[6];
11495   u8 dst = 0;
11496   u8 dst_val[6];
11497   u8 proto = 0;
11498   u16 proto_val;
11499   u8 tag1 = 0;
11500   u8 tag1_val[2];
11501   u8 tag2 = 0;
11502   u8 tag2_val[2];
11503   int len = 14;
11504   u8 ignore_tag1 = 0;
11505   u8 ignore_tag2 = 0;
11506   u8 cos1 = 0;
11507   u8 cos2 = 0;
11508   u32 cos1_val = 0;
11509   u32 cos2_val = 0;
11510
11511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11512     {
11513       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11514         src = 1;
11515       else
11516         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11517         dst = 1;
11518       else if (unformat (input, "proto %U",
11519                          unformat_ethernet_type_host_byte_order, &proto_val))
11520         proto = 1;
11521       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11522         tag1 = 1;
11523       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11524         tag2 = 1;
11525       else if (unformat (input, "ignore-tag1"))
11526         ignore_tag1 = 1;
11527       else if (unformat (input, "ignore-tag2"))
11528         ignore_tag2 = 1;
11529       else if (unformat (input, "cos1 %d", &cos1_val))
11530         cos1 = 1;
11531       else if (unformat (input, "cos2 %d", &cos2_val))
11532         cos2 = 1;
11533       else
11534         break;
11535     }
11536   if ((src + dst + proto + tag1 + tag2 +
11537        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11538     return 0;
11539
11540   if (tag1 || ignore_tag1 || cos1)
11541     len = 18;
11542   if (tag2 || ignore_tag2 || cos2)
11543     len = 22;
11544
11545   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11546
11547   if (dst)
11548     clib_memcpy (match, dst_val, 6);
11549
11550   if (src)
11551     clib_memcpy (match + 6, src_val, 6);
11552
11553   if (tag2)
11554     {
11555       /* inner vlan tag */
11556       match[19] = tag2_val[1];
11557       match[18] = tag2_val[0];
11558       if (cos2)
11559         match[18] |= (cos2_val & 0x7) << 5;
11560       if (proto)
11561         {
11562           match[21] = proto_val & 0xff;
11563           match[20] = proto_val >> 8;
11564         }
11565       if (tag1)
11566         {
11567           match[15] = tag1_val[1];
11568           match[14] = tag1_val[0];
11569         }
11570       if (cos1)
11571         match[14] |= (cos1_val & 0x7) << 5;
11572       *matchp = match;
11573       return 1;
11574     }
11575   if (tag1)
11576     {
11577       match[15] = tag1_val[1];
11578       match[14] = tag1_val[0];
11579       if (proto)
11580         {
11581           match[17] = proto_val & 0xff;
11582           match[16] = proto_val >> 8;
11583         }
11584       if (cos1)
11585         match[14] |= (cos1_val & 0x7) << 5;
11586
11587       *matchp = match;
11588       return 1;
11589     }
11590   if (cos2)
11591     match[18] |= (cos2_val & 0x7) << 5;
11592   if (cos1)
11593     match[14] |= (cos1_val & 0x7) << 5;
11594   if (proto)
11595     {
11596       match[13] = proto_val & 0xff;
11597       match[12] = proto_val >> 8;
11598     }
11599
11600   *matchp = match;
11601   return 1;
11602 }
11603
11604 uword
11605 unformat_qos_source (unformat_input_t * input, va_list * args)
11606 {
11607   int *qs = va_arg (*args, int *);
11608
11609   if (unformat (input, "ip"))
11610     *qs = QOS_SOURCE_IP;
11611   else if (unformat (input, "mpls"))
11612     *qs = QOS_SOURCE_MPLS;
11613   else if (unformat (input, "ext"))
11614     *qs = QOS_SOURCE_EXT;
11615   else if (unformat (input, "vlan"))
11616     *qs = QOS_SOURCE_VLAN;
11617   else
11618     return 0;
11619
11620   return 1;
11621 }
11622 #endif
11623
11624 uword
11625 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11626 {
11627   u8 **matchp = va_arg (*args, u8 **);
11628   u32 skip_n_vectors = va_arg (*args, u32);
11629   u32 match_n_vectors = va_arg (*args, u32);
11630
11631   u8 *match = 0;
11632   u8 *l2 = 0;
11633   u8 *l3 = 0;
11634   u8 *l4 = 0;
11635
11636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (input, "hex %U", unformat_hex_string, &match))
11639         ;
11640       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11641         ;
11642       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11643         ;
11644       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11645         ;
11646       else
11647         break;
11648     }
11649
11650   if (l4 && !l3)
11651     {
11652       vec_free (match);
11653       vec_free (l2);
11654       vec_free (l4);
11655       return 0;
11656     }
11657
11658   if (match || l2 || l3 || l4)
11659     {
11660       if (l2 || l3 || l4)
11661         {
11662           /* "Win a free Ethernet header in every packet" */
11663           if (l2 == 0)
11664             vec_validate_aligned (l2, 13, sizeof (u32x4));
11665           match = l2;
11666           if (vec_len (l3))
11667             {
11668               vec_append_aligned (match, l3, sizeof (u32x4));
11669               vec_free (l3);
11670             }
11671           if (vec_len (l4))
11672             {
11673               vec_append_aligned (match, l4, sizeof (u32x4));
11674               vec_free (l4);
11675             }
11676         }
11677
11678       /* Make sure the vector is big enough even if key is all 0's */
11679       vec_validate_aligned
11680         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11681          sizeof (u32x4));
11682
11683       /* Set size, include skipped vectors */
11684       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11685
11686       *matchp = match;
11687
11688       return 1;
11689     }
11690
11691   return 0;
11692 }
11693
11694 static int
11695 api_classify_add_del_session (vat_main_t * vam)
11696 {
11697   unformat_input_t *i = vam->input;
11698   vl_api_classify_add_del_session_t *mp;
11699   int is_add = 1;
11700   u32 table_index = ~0;
11701   u32 hit_next_index = ~0;
11702   u32 opaque_index = ~0;
11703   u8 *match = 0;
11704   i32 advance = 0;
11705   u32 skip_n_vectors = 0;
11706   u32 match_n_vectors = 0;
11707   u32 action = 0;
11708   u32 metadata = 0;
11709   int ret;
11710
11711   /*
11712    * Warning: you have to supply skip_n and match_n
11713    * because the API client cant simply look at the classify
11714    * table object.
11715    */
11716
11717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11718     {
11719       if (unformat (i, "del"))
11720         is_add = 0;
11721       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11722                          &hit_next_index))
11723         ;
11724       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11725                          &hit_next_index))
11726         ;
11727       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11728                          &hit_next_index))
11729         ;
11730       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11731         ;
11732       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11733         ;
11734       else if (unformat (i, "opaque-index %d", &opaque_index))
11735         ;
11736       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11737         ;
11738       else if (unformat (i, "match_n %d", &match_n_vectors))
11739         ;
11740       else if (unformat (i, "match %U", api_unformat_classify_match,
11741                          &match, skip_n_vectors, match_n_vectors))
11742         ;
11743       else if (unformat (i, "advance %d", &advance))
11744         ;
11745       else if (unformat (i, "table-index %d", &table_index))
11746         ;
11747       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11748         action = 1;
11749       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11750         action = 2;
11751       else if (unformat (i, "action %d", &action))
11752         ;
11753       else if (unformat (i, "metadata %d", &metadata))
11754         ;
11755       else
11756         break;
11757     }
11758
11759   if (table_index == ~0)
11760     {
11761       errmsg ("Table index required");
11762       return -99;
11763     }
11764
11765   if (is_add && match == 0)
11766     {
11767       errmsg ("Match value required");
11768       return -99;
11769     }
11770
11771   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11772
11773   mp->is_add = is_add;
11774   mp->table_index = ntohl (table_index);
11775   mp->hit_next_index = ntohl (hit_next_index);
11776   mp->opaque_index = ntohl (opaque_index);
11777   mp->advance = ntohl (advance);
11778   mp->action = action;
11779   mp->metadata = ntohl (metadata);
11780   mp->match_len = ntohl (vec_len (match));
11781   clib_memcpy (mp->match, match, vec_len (match));
11782   vec_free (match);
11783
11784   S (mp);
11785   W (ret);
11786   return ret;
11787 }
11788
11789 static int
11790 api_classify_set_interface_ip_table (vat_main_t * vam)
11791 {
11792   unformat_input_t *i = vam->input;
11793   vl_api_classify_set_interface_ip_table_t *mp;
11794   u32 sw_if_index;
11795   int sw_if_index_set;
11796   u32 table_index = ~0;
11797   u8 is_ipv6 = 0;
11798   int ret;
11799
11800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11801     {
11802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11803         sw_if_index_set = 1;
11804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "table %d", &table_index))
11807         ;
11808       else
11809         {
11810           clib_warning ("parse error '%U'", format_unformat_error, i);
11811           return -99;
11812         }
11813     }
11814
11815   if (sw_if_index_set == 0)
11816     {
11817       errmsg ("missing interface name or sw_if_index");
11818       return -99;
11819     }
11820
11821
11822   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11823
11824   mp->sw_if_index = ntohl (sw_if_index);
11825   mp->table_index = ntohl (table_index);
11826   mp->is_ipv6 = is_ipv6;
11827
11828   S (mp);
11829   W (ret);
11830   return ret;
11831 }
11832
11833 static int
11834 api_classify_set_interface_l2_tables (vat_main_t * vam)
11835 {
11836   unformat_input_t *i = vam->input;
11837   vl_api_classify_set_interface_l2_tables_t *mp;
11838   u32 sw_if_index;
11839   int sw_if_index_set;
11840   u32 ip4_table_index = ~0;
11841   u32 ip6_table_index = ~0;
11842   u32 other_table_index = ~0;
11843   u32 is_input = 1;
11844   int ret;
11845
11846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11847     {
11848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11849         sw_if_index_set = 1;
11850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11851         sw_if_index_set = 1;
11852       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11853         ;
11854       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11855         ;
11856       else if (unformat (i, "other-table %d", &other_table_index))
11857         ;
11858       else if (unformat (i, "is-input %d", &is_input))
11859         ;
11860       else
11861         {
11862           clib_warning ("parse error '%U'", format_unformat_error, i);
11863           return -99;
11864         }
11865     }
11866
11867   if (sw_if_index_set == 0)
11868     {
11869       errmsg ("missing interface name or sw_if_index");
11870       return -99;
11871     }
11872
11873
11874   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11875
11876   mp->sw_if_index = ntohl (sw_if_index);
11877   mp->ip4_table_index = ntohl (ip4_table_index);
11878   mp->ip6_table_index = ntohl (ip6_table_index);
11879   mp->other_table_index = ntohl (other_table_index);
11880   mp->is_input = (u8) is_input;
11881
11882   S (mp);
11883   W (ret);
11884   return ret;
11885 }
11886
11887 static int
11888 api_set_ipfix_exporter (vat_main_t * vam)
11889 {
11890   unformat_input_t *i = vam->input;
11891   vl_api_set_ipfix_exporter_t *mp;
11892   ip4_address_t collector_address;
11893   u8 collector_address_set = 0;
11894   u32 collector_port = ~0;
11895   ip4_address_t src_address;
11896   u8 src_address_set = 0;
11897   u32 vrf_id = ~0;
11898   u32 path_mtu = ~0;
11899   u32 template_interval = ~0;
11900   u8 udp_checksum = 0;
11901   int ret;
11902
11903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11904     {
11905       if (unformat (i, "collector_address %U", unformat_ip4_address,
11906                     &collector_address))
11907         collector_address_set = 1;
11908       else if (unformat (i, "collector_port %d", &collector_port))
11909         ;
11910       else if (unformat (i, "src_address %U", unformat_ip4_address,
11911                          &src_address))
11912         src_address_set = 1;
11913       else if (unformat (i, "vrf_id %d", &vrf_id))
11914         ;
11915       else if (unformat (i, "path_mtu %d", &path_mtu))
11916         ;
11917       else if (unformat (i, "template_interval %d", &template_interval))
11918         ;
11919       else if (unformat (i, "udp_checksum"))
11920         udp_checksum = 1;
11921       else
11922         break;
11923     }
11924
11925   if (collector_address_set == 0)
11926     {
11927       errmsg ("collector_address required");
11928       return -99;
11929     }
11930
11931   if (src_address_set == 0)
11932     {
11933       errmsg ("src_address required");
11934       return -99;
11935     }
11936
11937   M (SET_IPFIX_EXPORTER, mp);
11938
11939   memcpy (mp->collector_address, collector_address.data,
11940           sizeof (collector_address.data));
11941   mp->collector_port = htons ((u16) collector_port);
11942   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11943   mp->vrf_id = htonl (vrf_id);
11944   mp->path_mtu = htonl (path_mtu);
11945   mp->template_interval = htonl (template_interval);
11946   mp->udp_checksum = udp_checksum;
11947
11948   S (mp);
11949   W (ret);
11950   return ret;
11951 }
11952
11953 static int
11954 api_set_ipfix_classify_stream (vat_main_t * vam)
11955 {
11956   unformat_input_t *i = vam->input;
11957   vl_api_set_ipfix_classify_stream_t *mp;
11958   u32 domain_id = 0;
11959   u32 src_port = UDP_DST_PORT_ipfix;
11960   int ret;
11961
11962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11963     {
11964       if (unformat (i, "domain %d", &domain_id))
11965         ;
11966       else if (unformat (i, "src_port %d", &src_port))
11967         ;
11968       else
11969         {
11970           errmsg ("unknown input `%U'", format_unformat_error, i);
11971           return -99;
11972         }
11973     }
11974
11975   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11976
11977   mp->domain_id = htonl (domain_id);
11978   mp->src_port = htons ((u16) src_port);
11979
11980   S (mp);
11981   W (ret);
11982   return ret;
11983 }
11984
11985 static int
11986 api_ipfix_classify_table_add_del (vat_main_t * vam)
11987 {
11988   unformat_input_t *i = vam->input;
11989   vl_api_ipfix_classify_table_add_del_t *mp;
11990   int is_add = -1;
11991   u32 classify_table_index = ~0;
11992   u8 ip_version = 0;
11993   u8 transport_protocol = 255;
11994   int ret;
11995
11996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (i, "add"))
11999         is_add = 1;
12000       else if (unformat (i, "del"))
12001         is_add = 0;
12002       else if (unformat (i, "table %d", &classify_table_index))
12003         ;
12004       else if (unformat (i, "ip4"))
12005         ip_version = 4;
12006       else if (unformat (i, "ip6"))
12007         ip_version = 6;
12008       else if (unformat (i, "tcp"))
12009         transport_protocol = 6;
12010       else if (unformat (i, "udp"))
12011         transport_protocol = 17;
12012       else
12013         {
12014           errmsg ("unknown input `%U'", format_unformat_error, i);
12015           return -99;
12016         }
12017     }
12018
12019   if (is_add == -1)
12020     {
12021       errmsg ("expecting: add|del");
12022       return -99;
12023     }
12024   if (classify_table_index == ~0)
12025     {
12026       errmsg ("classifier table not specified");
12027       return -99;
12028     }
12029   if (ip_version == 0)
12030     {
12031       errmsg ("IP version not specified");
12032       return -99;
12033     }
12034
12035   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12036
12037   mp->is_add = is_add;
12038   mp->table_id = htonl (classify_table_index);
12039   mp->ip_version = ip_version;
12040   mp->transport_protocol = transport_protocol;
12041
12042   S (mp);
12043   W (ret);
12044   return ret;
12045 }
12046
12047 static int
12048 api_get_node_index (vat_main_t * vam)
12049 {
12050   unformat_input_t *i = vam->input;
12051   vl_api_get_node_index_t *mp;
12052   u8 *name = 0;
12053   int ret;
12054
12055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12056     {
12057       if (unformat (i, "node %s", &name))
12058         ;
12059       else
12060         break;
12061     }
12062   if (name == 0)
12063     {
12064       errmsg ("node name required");
12065       return -99;
12066     }
12067   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12068     {
12069       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12070       return -99;
12071     }
12072
12073   M (GET_NODE_INDEX, mp);
12074   clib_memcpy (mp->node_name, name, vec_len (name));
12075   vec_free (name);
12076
12077   S (mp);
12078   W (ret);
12079   return ret;
12080 }
12081
12082 static int
12083 api_get_next_index (vat_main_t * vam)
12084 {
12085   unformat_input_t *i = vam->input;
12086   vl_api_get_next_index_t *mp;
12087   u8 *node_name = 0, *next_node_name = 0;
12088   int ret;
12089
12090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12091     {
12092       if (unformat (i, "node-name %s", &node_name))
12093         ;
12094       else if (unformat (i, "next-node-name %s", &next_node_name))
12095         break;
12096     }
12097
12098   if (node_name == 0)
12099     {
12100       errmsg ("node name required");
12101       return -99;
12102     }
12103   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12104     {
12105       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12106       return -99;
12107     }
12108
12109   if (next_node_name == 0)
12110     {
12111       errmsg ("next node name required");
12112       return -99;
12113     }
12114   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12115     {
12116       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12117       return -99;
12118     }
12119
12120   M (GET_NEXT_INDEX, mp);
12121   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12122   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12123   vec_free (node_name);
12124   vec_free (next_node_name);
12125
12126   S (mp);
12127   W (ret);
12128   return ret;
12129 }
12130
12131 static int
12132 api_add_node_next (vat_main_t * vam)
12133 {
12134   unformat_input_t *i = vam->input;
12135   vl_api_add_node_next_t *mp;
12136   u8 *name = 0;
12137   u8 *next = 0;
12138   int ret;
12139
12140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12141     {
12142       if (unformat (i, "node %s", &name))
12143         ;
12144       else if (unformat (i, "next %s", &next))
12145         ;
12146       else
12147         break;
12148     }
12149   if (name == 0)
12150     {
12151       errmsg ("node name required");
12152       return -99;
12153     }
12154   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12155     {
12156       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12157       return -99;
12158     }
12159   if (next == 0)
12160     {
12161       errmsg ("next node required");
12162       return -99;
12163     }
12164   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12165     {
12166       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12167       return -99;
12168     }
12169
12170   M (ADD_NODE_NEXT, mp);
12171   clib_memcpy (mp->node_name, name, vec_len (name));
12172   clib_memcpy (mp->next_name, next, vec_len (next));
12173   vec_free (name);
12174   vec_free (next);
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static int
12182 api_l2tpv3_create_tunnel (vat_main_t * vam)
12183 {
12184   unformat_input_t *i = vam->input;
12185   ip6_address_t client_address, our_address;
12186   int client_address_set = 0;
12187   int our_address_set = 0;
12188   u32 local_session_id = 0;
12189   u32 remote_session_id = 0;
12190   u64 local_cookie = 0;
12191   u64 remote_cookie = 0;
12192   u8 l2_sublayer_present = 0;
12193   vl_api_l2tpv3_create_tunnel_t *mp;
12194   int ret;
12195
12196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12197     {
12198       if (unformat (i, "client_address %U", unformat_ip6_address,
12199                     &client_address))
12200         client_address_set = 1;
12201       else if (unformat (i, "our_address %U", unformat_ip6_address,
12202                          &our_address))
12203         our_address_set = 1;
12204       else if (unformat (i, "local_session_id %d", &local_session_id))
12205         ;
12206       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12207         ;
12208       else if (unformat (i, "local_cookie %lld", &local_cookie))
12209         ;
12210       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12211         ;
12212       else if (unformat (i, "l2-sublayer-present"))
12213         l2_sublayer_present = 1;
12214       else
12215         break;
12216     }
12217
12218   if (client_address_set == 0)
12219     {
12220       errmsg ("client_address required");
12221       return -99;
12222     }
12223
12224   if (our_address_set == 0)
12225     {
12226       errmsg ("our_address required");
12227       return -99;
12228     }
12229
12230   M (L2TPV3_CREATE_TUNNEL, mp);
12231
12232   clib_memcpy (mp->client_address, client_address.as_u8,
12233                sizeof (mp->client_address));
12234
12235   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12236
12237   mp->local_session_id = ntohl (local_session_id);
12238   mp->remote_session_id = ntohl (remote_session_id);
12239   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12240   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12241   mp->l2_sublayer_present = l2_sublayer_present;
12242   mp->is_ipv6 = 1;
12243
12244   S (mp);
12245   W (ret);
12246   return ret;
12247 }
12248
12249 static int
12250 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   u32 sw_if_index;
12254   u8 sw_if_index_set = 0;
12255   u64 new_local_cookie = 0;
12256   u64 new_remote_cookie = 0;
12257   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12258   int ret;
12259
12260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12261     {
12262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12263         sw_if_index_set = 1;
12264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12265         sw_if_index_set = 1;
12266       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12267         ;
12268       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12269         ;
12270       else
12271         break;
12272     }
12273
12274   if (sw_if_index_set == 0)
12275     {
12276       errmsg ("missing interface name or sw_if_index");
12277       return -99;
12278     }
12279
12280   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12281
12282   mp->sw_if_index = ntohl (sw_if_index);
12283   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12284   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12285
12286   S (mp);
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static int
12292 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12293 {
12294   unformat_input_t *i = vam->input;
12295   vl_api_l2tpv3_interface_enable_disable_t *mp;
12296   u32 sw_if_index;
12297   u8 sw_if_index_set = 0;
12298   u8 enable_disable = 1;
12299   int ret;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12304         sw_if_index_set = 1;
12305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12306         sw_if_index_set = 1;
12307       else if (unformat (i, "enable"))
12308         enable_disable = 1;
12309       else if (unformat (i, "disable"))
12310         enable_disable = 0;
12311       else
12312         break;
12313     }
12314
12315   if (sw_if_index_set == 0)
12316     {
12317       errmsg ("missing interface name or sw_if_index");
12318       return -99;
12319     }
12320
12321   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12322
12323   mp->sw_if_index = ntohl (sw_if_index);
12324   mp->enable_disable = enable_disable;
12325
12326   S (mp);
12327   W (ret);
12328   return ret;
12329 }
12330
12331 static int
12332 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12333 {
12334   unformat_input_t *i = vam->input;
12335   vl_api_l2tpv3_set_lookup_key_t *mp;
12336   u8 key = ~0;
12337   int ret;
12338
12339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12340     {
12341       if (unformat (i, "lookup_v6_src"))
12342         key = L2T_LOOKUP_SRC_ADDRESS;
12343       else if (unformat (i, "lookup_v6_dst"))
12344         key = L2T_LOOKUP_DST_ADDRESS;
12345       else if (unformat (i, "lookup_session_id"))
12346         key = L2T_LOOKUP_SESSION_ID;
12347       else
12348         break;
12349     }
12350
12351   if (key == (u8) ~ 0)
12352     {
12353       errmsg ("l2tp session lookup key unset");
12354       return -99;
12355     }
12356
12357   M (L2TPV3_SET_LOOKUP_KEY, mp);
12358
12359   mp->key = key;
12360
12361   S (mp);
12362   W (ret);
12363   return ret;
12364 }
12365
12366 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12367   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12368 {
12369   vat_main_t *vam = &vat_main;
12370
12371   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12372          format_ip6_address, mp->our_address,
12373          format_ip6_address, mp->client_address,
12374          clib_net_to_host_u32 (mp->sw_if_index));
12375
12376   print (vam->ofp,
12377          "   local cookies %016llx %016llx remote cookie %016llx",
12378          clib_net_to_host_u64 (mp->local_cookie[0]),
12379          clib_net_to_host_u64 (mp->local_cookie[1]),
12380          clib_net_to_host_u64 (mp->remote_cookie));
12381
12382   print (vam->ofp, "   local session-id %d remote session-id %d",
12383          clib_net_to_host_u32 (mp->local_session_id),
12384          clib_net_to_host_u32 (mp->remote_session_id));
12385
12386   print (vam->ofp, "   l2 specific sublayer %s\n",
12387          mp->l2_sublayer_present ? "preset" : "absent");
12388
12389 }
12390
12391 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12392   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12393 {
12394   vat_main_t *vam = &vat_main;
12395   vat_json_node_t *node = NULL;
12396   struct in6_addr addr;
12397
12398   if (VAT_JSON_ARRAY != vam->json_tree.type)
12399     {
12400       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12401       vat_json_init_array (&vam->json_tree);
12402     }
12403   node = vat_json_array_add (&vam->json_tree);
12404
12405   vat_json_init_object (node);
12406
12407   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12408   vat_json_object_add_ip6 (node, "our_address", addr);
12409   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12410   vat_json_object_add_ip6 (node, "client_address", addr);
12411
12412   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12413   vat_json_init_array (lc);
12414   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12415   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12416   vat_json_object_add_uint (node, "remote_cookie",
12417                             clib_net_to_host_u64 (mp->remote_cookie));
12418
12419   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12420   vat_json_object_add_uint (node, "local_session_id",
12421                             clib_net_to_host_u32 (mp->local_session_id));
12422   vat_json_object_add_uint (node, "remote_session_id",
12423                             clib_net_to_host_u32 (mp->remote_session_id));
12424   vat_json_object_add_string_copy (node, "l2_sublayer",
12425                                    mp->l2_sublayer_present ? (u8 *) "present"
12426                                    : (u8 *) "absent");
12427 }
12428
12429 static int
12430 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12431 {
12432   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12433   vl_api_control_ping_t *mp_ping;
12434   int ret;
12435
12436   /* Get list of l2tpv3-tunnel interfaces */
12437   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12438   S (mp);
12439
12440   /* Use a control ping for synchronization */
12441   MPING (CONTROL_PING, mp_ping);
12442   S (mp_ping);
12443
12444   W (ret);
12445   return ret;
12446 }
12447
12448
12449 static void vl_api_sw_interface_tap_v2_details_t_handler
12450   (vl_api_sw_interface_tap_v2_details_t * mp)
12451 {
12452   vat_main_t *vam = &vat_main;
12453
12454   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12455                     mp->host_ip4_prefix_len);
12456   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12457                     mp->host_ip6_prefix_len);
12458
12459   print (vam->ofp,
12460          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12461          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12462          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12463          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12464          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12465
12466   vec_free (ip4);
12467   vec_free (ip6);
12468 }
12469
12470 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12471   (vl_api_sw_interface_tap_v2_details_t * mp)
12472 {
12473   vat_main_t *vam = &vat_main;
12474   vat_json_node_t *node = NULL;
12475
12476   if (VAT_JSON_ARRAY != vam->json_tree.type)
12477     {
12478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12479       vat_json_init_array (&vam->json_tree);
12480     }
12481   node = vat_json_array_add (&vam->json_tree);
12482
12483   vat_json_init_object (node);
12484   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12485   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12486   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12487   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12488   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12489   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12490   vat_json_object_add_string_copy (node, "host_mac_addr",
12491                                    format (0, "%U", format_ethernet_address,
12492                                            &mp->host_mac_addr));
12493   vat_json_object_add_string_copy (node, "host_namespace",
12494                                    mp->host_namespace);
12495   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12496   vat_json_object_add_string_copy (node, "host_ip4_addr",
12497                                    format (0, "%U/%d", format_ip4_address,
12498                                            mp->host_ip4_addr,
12499                                            mp->host_ip4_prefix_len));
12500   vat_json_object_add_string_copy (node, "host_ip6_addr",
12501                                    format (0, "%U/%d", format_ip6_address,
12502                                            mp->host_ip6_addr,
12503                                            mp->host_ip6_prefix_len));
12504
12505 }
12506
12507 static int
12508 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12509 {
12510   vl_api_sw_interface_tap_v2_dump_t *mp;
12511   vl_api_control_ping_t *mp_ping;
12512   int ret;
12513
12514   print (vam->ofp,
12515          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12516          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12517          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12518          "host_ip6_addr");
12519
12520   /* Get list of tap interfaces */
12521   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12522   S (mp);
12523
12524   /* Use a control ping for synchronization */
12525   MPING (CONTROL_PING, mp_ping);
12526   S (mp_ping);
12527
12528   W (ret);
12529   return ret;
12530 }
12531
12532 static void vl_api_sw_interface_virtio_pci_details_t_handler
12533   (vl_api_sw_interface_virtio_pci_details_t * mp)
12534 {
12535   vat_main_t *vam = &vat_main;
12536
12537   typedef union
12538   {
12539     struct
12540     {
12541       u16 domain;
12542       u8 bus;
12543       u8 slot:5;
12544       u8 function:3;
12545     };
12546     u32 as_u32;
12547   } pci_addr_t;
12548   pci_addr_t addr;
12549   addr.as_u32 = ntohl (mp->pci_addr);
12550   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12551                          addr.slot, addr.function);
12552
12553   print (vam->ofp,
12554          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12555          pci_addr, ntohl (mp->sw_if_index),
12556          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12557          format_ethernet_address, mp->mac_addr,
12558          clib_net_to_host_u64 (mp->features));
12559   vec_free (pci_addr);
12560 }
12561
12562 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12563   (vl_api_sw_interface_virtio_pci_details_t * mp)
12564 {
12565   vat_main_t *vam = &vat_main;
12566   vat_json_node_t *node = NULL;
12567
12568   if (VAT_JSON_ARRAY != vam->json_tree.type)
12569     {
12570       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12571       vat_json_init_array (&vam->json_tree);
12572     }
12573   node = vat_json_array_add (&vam->json_tree);
12574
12575   vat_json_init_object (node);
12576   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12577   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12578   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12579   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12580   vat_json_object_add_uint (node, "features",
12581                             clib_net_to_host_u64 (mp->features));
12582   vat_json_object_add_string_copy (node, "mac_addr",
12583                                    format (0, "%U", format_ethernet_address,
12584                                            &mp->mac_addr));
12585 }
12586
12587 static int
12588 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12589 {
12590   vl_api_sw_interface_virtio_pci_dump_t *mp;
12591   vl_api_control_ping_t *mp_ping;
12592   int ret;
12593
12594   print (vam->ofp,
12595          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12596          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12597          "mac_addr", "features");
12598
12599   /* Get list of tap interfaces */
12600   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12601   S (mp);
12602
12603   /* Use a control ping for synchronization */
12604   MPING (CONTROL_PING, mp_ping);
12605   S (mp_ping);
12606
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_vxlan_offload_rx (vat_main_t * vam)
12613 {
12614   unformat_input_t *line_input = vam->input;
12615   vl_api_vxlan_offload_rx_t *mp;
12616   u32 hw_if_index = ~0, rx_if_index = ~0;
12617   u8 is_add = 1;
12618   int ret;
12619
12620   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12621     {
12622       if (unformat (line_input, "del"))
12623         is_add = 0;
12624       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12625                          &hw_if_index))
12626         ;
12627       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12628         ;
12629       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12630                          &rx_if_index))
12631         ;
12632       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12633         ;
12634       else
12635         {
12636           errmsg ("parse error '%U'", format_unformat_error, line_input);
12637           return -99;
12638         }
12639     }
12640
12641   if (hw_if_index == ~0)
12642     {
12643       errmsg ("no hw interface");
12644       return -99;
12645     }
12646
12647   if (rx_if_index == ~0)
12648     {
12649       errmsg ("no rx tunnel");
12650       return -99;
12651     }
12652
12653   M (VXLAN_OFFLOAD_RX, mp);
12654
12655   mp->hw_if_index = ntohl (hw_if_index);
12656   mp->sw_if_index = ntohl (rx_if_index);
12657   mp->enable = is_add;
12658
12659   S (mp);
12660   W (ret);
12661   return ret;
12662 }
12663
12664 static uword unformat_vxlan_decap_next
12665   (unformat_input_t * input, va_list * args)
12666 {
12667   u32 *result = va_arg (*args, u32 *);
12668   u32 tmp;
12669
12670   if (unformat (input, "l2"))
12671     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12672   else if (unformat (input, "%d", &tmp))
12673     *result = tmp;
12674   else
12675     return 0;
12676   return 1;
12677 }
12678
12679 static int
12680 api_vxlan_add_del_tunnel (vat_main_t * vam)
12681 {
12682   unformat_input_t *line_input = vam->input;
12683   vl_api_vxlan_add_del_tunnel_t *mp;
12684   ip46_address_t src, dst;
12685   u8 is_add = 1;
12686   u8 ipv4_set = 0, ipv6_set = 0;
12687   u8 src_set = 0;
12688   u8 dst_set = 0;
12689   u8 grp_set = 0;
12690   u32 instance = ~0;
12691   u32 mcast_sw_if_index = ~0;
12692   u32 encap_vrf_id = 0;
12693   u32 decap_next_index = ~0;
12694   u32 vni = 0;
12695   int ret;
12696
12697   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12698   clib_memset (&src, 0, sizeof src);
12699   clib_memset (&dst, 0, sizeof dst);
12700
12701   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12702     {
12703       if (unformat (line_input, "del"))
12704         is_add = 0;
12705       else if (unformat (line_input, "instance %d", &instance))
12706         ;
12707       else
12708         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12709         {
12710           ipv4_set = 1;
12711           src_set = 1;
12712         }
12713       else
12714         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12715         {
12716           ipv4_set = 1;
12717           dst_set = 1;
12718         }
12719       else
12720         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12721         {
12722           ipv6_set = 1;
12723           src_set = 1;
12724         }
12725       else
12726         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12727         {
12728           ipv6_set = 1;
12729           dst_set = 1;
12730         }
12731       else if (unformat (line_input, "group %U %U",
12732                          unformat_ip4_address, &dst.ip4,
12733                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12734         {
12735           grp_set = dst_set = 1;
12736           ipv4_set = 1;
12737         }
12738       else if (unformat (line_input, "group %U",
12739                          unformat_ip4_address, &dst.ip4))
12740         {
12741           grp_set = dst_set = 1;
12742           ipv4_set = 1;
12743         }
12744       else if (unformat (line_input, "group %U %U",
12745                          unformat_ip6_address, &dst.ip6,
12746                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12747         {
12748           grp_set = dst_set = 1;
12749           ipv6_set = 1;
12750         }
12751       else if (unformat (line_input, "group %U",
12752                          unformat_ip6_address, &dst.ip6))
12753         {
12754           grp_set = dst_set = 1;
12755           ipv6_set = 1;
12756         }
12757       else
12758         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12759         ;
12760       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12761         ;
12762       else if (unformat (line_input, "decap-next %U",
12763                          unformat_vxlan_decap_next, &decap_next_index))
12764         ;
12765       else if (unformat (line_input, "vni %d", &vni))
12766         ;
12767       else
12768         {
12769           errmsg ("parse error '%U'", format_unformat_error, line_input);
12770           return -99;
12771         }
12772     }
12773
12774   if (src_set == 0)
12775     {
12776       errmsg ("tunnel src address not specified");
12777       return -99;
12778     }
12779   if (dst_set == 0)
12780     {
12781       errmsg ("tunnel dst address not specified");
12782       return -99;
12783     }
12784
12785   if (grp_set && !ip46_address_is_multicast (&dst))
12786     {
12787       errmsg ("tunnel group address not multicast");
12788       return -99;
12789     }
12790   if (grp_set && mcast_sw_if_index == ~0)
12791     {
12792       errmsg ("tunnel nonexistent multicast device");
12793       return -99;
12794     }
12795   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12796     {
12797       errmsg ("tunnel dst address must be unicast");
12798       return -99;
12799     }
12800
12801
12802   if (ipv4_set && ipv6_set)
12803     {
12804       errmsg ("both IPv4 and IPv6 addresses specified");
12805       return -99;
12806     }
12807
12808   if ((vni == 0) || (vni >> 24))
12809     {
12810       errmsg ("vni not specified or out of range");
12811       return -99;
12812     }
12813
12814   M (VXLAN_ADD_DEL_TUNNEL, mp);
12815
12816   if (ipv6_set)
12817     {
12818       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12819       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12820     }
12821   else
12822     {
12823       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12824       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12825     }
12826
12827   mp->instance = htonl (instance);
12828   mp->encap_vrf_id = ntohl (encap_vrf_id);
12829   mp->decap_next_index = ntohl (decap_next_index);
12830   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12831   mp->vni = ntohl (vni);
12832   mp->is_add = is_add;
12833   mp->is_ipv6 = ipv6_set;
12834
12835   S (mp);
12836   W (ret);
12837   return ret;
12838 }
12839
12840 static void vl_api_vxlan_tunnel_details_t_handler
12841   (vl_api_vxlan_tunnel_details_t * mp)
12842 {
12843   vat_main_t *vam = &vat_main;
12844   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12845   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12846
12847   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12848          ntohl (mp->sw_if_index),
12849          ntohl (mp->instance),
12850          format_ip46_address, &src, IP46_TYPE_ANY,
12851          format_ip46_address, &dst, IP46_TYPE_ANY,
12852          ntohl (mp->encap_vrf_id),
12853          ntohl (mp->decap_next_index), ntohl (mp->vni),
12854          ntohl (mp->mcast_sw_if_index));
12855 }
12856
12857 static void vl_api_vxlan_tunnel_details_t_handler_json
12858   (vl_api_vxlan_tunnel_details_t * mp)
12859 {
12860   vat_main_t *vam = &vat_main;
12861   vat_json_node_t *node = NULL;
12862
12863   if (VAT_JSON_ARRAY != vam->json_tree.type)
12864     {
12865       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12866       vat_json_init_array (&vam->json_tree);
12867     }
12868   node = vat_json_array_add (&vam->json_tree);
12869
12870   vat_json_init_object (node);
12871   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12872
12873   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12874
12875   if (mp->is_ipv6)
12876     {
12877       struct in6_addr ip6;
12878
12879       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12880       vat_json_object_add_ip6 (node, "src_address", ip6);
12881       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12882       vat_json_object_add_ip6 (node, "dst_address", ip6);
12883     }
12884   else
12885     {
12886       struct in_addr ip4;
12887
12888       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12889       vat_json_object_add_ip4 (node, "src_address", ip4);
12890       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12891       vat_json_object_add_ip4 (node, "dst_address", ip4);
12892     }
12893   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12894   vat_json_object_add_uint (node, "decap_next_index",
12895                             ntohl (mp->decap_next_index));
12896   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12897   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12898   vat_json_object_add_uint (node, "mcast_sw_if_index",
12899                             ntohl (mp->mcast_sw_if_index));
12900 }
12901
12902 static int
12903 api_vxlan_tunnel_dump (vat_main_t * vam)
12904 {
12905   unformat_input_t *i = vam->input;
12906   vl_api_vxlan_tunnel_dump_t *mp;
12907   vl_api_control_ping_t *mp_ping;
12908   u32 sw_if_index;
12909   u8 sw_if_index_set = 0;
12910   int ret;
12911
12912   /* Parse args required to build the message */
12913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12914     {
12915       if (unformat (i, "sw_if_index %d", &sw_if_index))
12916         sw_if_index_set = 1;
12917       else
12918         break;
12919     }
12920
12921   if (sw_if_index_set == 0)
12922     {
12923       sw_if_index = ~0;
12924     }
12925
12926   if (!vam->json_output)
12927     {
12928       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12929              "sw_if_index", "instance", "src_address", "dst_address",
12930              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12931     }
12932
12933   /* Get list of vxlan-tunnel interfaces */
12934   M (VXLAN_TUNNEL_DUMP, mp);
12935
12936   mp->sw_if_index = htonl (sw_if_index);
12937
12938   S (mp);
12939
12940   /* Use a control ping for synchronization */
12941   MPING (CONTROL_PING, mp_ping);
12942   S (mp_ping);
12943
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static uword unformat_geneve_decap_next
12949   (unformat_input_t * input, va_list * args)
12950 {
12951   u32 *result = va_arg (*args, u32 *);
12952   u32 tmp;
12953
12954   if (unformat (input, "l2"))
12955     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12956   else if (unformat (input, "%d", &tmp))
12957     *result = tmp;
12958   else
12959     return 0;
12960   return 1;
12961 }
12962
12963 static int
12964 api_geneve_add_del_tunnel (vat_main_t * vam)
12965 {
12966   unformat_input_t *line_input = vam->input;
12967   vl_api_geneve_add_del_tunnel_t *mp;
12968   ip46_address_t src, dst;
12969   u8 is_add = 1;
12970   u8 ipv4_set = 0, ipv6_set = 0;
12971   u8 src_set = 0;
12972   u8 dst_set = 0;
12973   u8 grp_set = 0;
12974   u32 mcast_sw_if_index = ~0;
12975   u32 encap_vrf_id = 0;
12976   u32 decap_next_index = ~0;
12977   u32 vni = 0;
12978   int ret;
12979
12980   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12981   clib_memset (&src, 0, sizeof src);
12982   clib_memset (&dst, 0, sizeof dst);
12983
12984   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12985     {
12986       if (unformat (line_input, "del"))
12987         is_add = 0;
12988       else
12989         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12990         {
12991           ipv4_set = 1;
12992           src_set = 1;
12993         }
12994       else
12995         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12996         {
12997           ipv4_set = 1;
12998           dst_set = 1;
12999         }
13000       else
13001         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13002         {
13003           ipv6_set = 1;
13004           src_set = 1;
13005         }
13006       else
13007         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13008         {
13009           ipv6_set = 1;
13010           dst_set = 1;
13011         }
13012       else if (unformat (line_input, "group %U %U",
13013                          unformat_ip4_address, &dst.ip4,
13014                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13015         {
13016           grp_set = dst_set = 1;
13017           ipv4_set = 1;
13018         }
13019       else if (unformat (line_input, "group %U",
13020                          unformat_ip4_address, &dst.ip4))
13021         {
13022           grp_set = dst_set = 1;
13023           ipv4_set = 1;
13024         }
13025       else if (unformat (line_input, "group %U %U",
13026                          unformat_ip6_address, &dst.ip6,
13027                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13028         {
13029           grp_set = dst_set = 1;
13030           ipv6_set = 1;
13031         }
13032       else if (unformat (line_input, "group %U",
13033                          unformat_ip6_address, &dst.ip6))
13034         {
13035           grp_set = dst_set = 1;
13036           ipv6_set = 1;
13037         }
13038       else
13039         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13040         ;
13041       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13042         ;
13043       else if (unformat (line_input, "decap-next %U",
13044                          unformat_geneve_decap_next, &decap_next_index))
13045         ;
13046       else if (unformat (line_input, "vni %d", &vni))
13047         ;
13048       else
13049         {
13050           errmsg ("parse error '%U'", format_unformat_error, line_input);
13051           return -99;
13052         }
13053     }
13054
13055   if (src_set == 0)
13056     {
13057       errmsg ("tunnel src address not specified");
13058       return -99;
13059     }
13060   if (dst_set == 0)
13061     {
13062       errmsg ("tunnel dst address not specified");
13063       return -99;
13064     }
13065
13066   if (grp_set && !ip46_address_is_multicast (&dst))
13067     {
13068       errmsg ("tunnel group address not multicast");
13069       return -99;
13070     }
13071   if (grp_set && mcast_sw_if_index == ~0)
13072     {
13073       errmsg ("tunnel nonexistent multicast device");
13074       return -99;
13075     }
13076   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13077     {
13078       errmsg ("tunnel dst address must be unicast");
13079       return -99;
13080     }
13081
13082
13083   if (ipv4_set && ipv6_set)
13084     {
13085       errmsg ("both IPv4 and IPv6 addresses specified");
13086       return -99;
13087     }
13088
13089   if ((vni == 0) || (vni >> 24))
13090     {
13091       errmsg ("vni not specified or out of range");
13092       return -99;
13093     }
13094
13095   M (GENEVE_ADD_DEL_TUNNEL, mp);
13096
13097   if (ipv6_set)
13098     {
13099       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13100       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13101     }
13102   else
13103     {
13104       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13105       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13106     }
13107   mp->encap_vrf_id = ntohl (encap_vrf_id);
13108   mp->decap_next_index = ntohl (decap_next_index);
13109   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13110   mp->vni = ntohl (vni);
13111   mp->is_add = is_add;
13112   mp->is_ipv6 = ipv6_set;
13113
13114   S (mp);
13115   W (ret);
13116   return ret;
13117 }
13118
13119 static void vl_api_geneve_tunnel_details_t_handler
13120   (vl_api_geneve_tunnel_details_t * mp)
13121 {
13122   vat_main_t *vam = &vat_main;
13123   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13124   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13125
13126   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13127          ntohl (mp->sw_if_index),
13128          format_ip46_address, &src, IP46_TYPE_ANY,
13129          format_ip46_address, &dst, IP46_TYPE_ANY,
13130          ntohl (mp->encap_vrf_id),
13131          ntohl (mp->decap_next_index), ntohl (mp->vni),
13132          ntohl (mp->mcast_sw_if_index));
13133 }
13134
13135 static void vl_api_geneve_tunnel_details_t_handler_json
13136   (vl_api_geneve_tunnel_details_t * mp)
13137 {
13138   vat_main_t *vam = &vat_main;
13139   vat_json_node_t *node = NULL;
13140
13141   if (VAT_JSON_ARRAY != vam->json_tree.type)
13142     {
13143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13144       vat_json_init_array (&vam->json_tree);
13145     }
13146   node = vat_json_array_add (&vam->json_tree);
13147
13148   vat_json_init_object (node);
13149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13150   if (mp->is_ipv6)
13151     {
13152       struct in6_addr ip6;
13153
13154       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13155       vat_json_object_add_ip6 (node, "src_address", ip6);
13156       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13157       vat_json_object_add_ip6 (node, "dst_address", ip6);
13158     }
13159   else
13160     {
13161       struct in_addr ip4;
13162
13163       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13164       vat_json_object_add_ip4 (node, "src_address", ip4);
13165       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13166       vat_json_object_add_ip4 (node, "dst_address", ip4);
13167     }
13168   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13169   vat_json_object_add_uint (node, "decap_next_index",
13170                             ntohl (mp->decap_next_index));
13171   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13172   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13173   vat_json_object_add_uint (node, "mcast_sw_if_index",
13174                             ntohl (mp->mcast_sw_if_index));
13175 }
13176
13177 static int
13178 api_geneve_tunnel_dump (vat_main_t * vam)
13179 {
13180   unformat_input_t *i = vam->input;
13181   vl_api_geneve_tunnel_dump_t *mp;
13182   vl_api_control_ping_t *mp_ping;
13183   u32 sw_if_index;
13184   u8 sw_if_index_set = 0;
13185   int ret;
13186
13187   /* Parse args required to build the message */
13188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189     {
13190       if (unformat (i, "sw_if_index %d", &sw_if_index))
13191         sw_if_index_set = 1;
13192       else
13193         break;
13194     }
13195
13196   if (sw_if_index_set == 0)
13197     {
13198       sw_if_index = ~0;
13199     }
13200
13201   if (!vam->json_output)
13202     {
13203       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13204              "sw_if_index", "local_address", "remote_address",
13205              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13206     }
13207
13208   /* Get list of geneve-tunnel interfaces */
13209   M (GENEVE_TUNNEL_DUMP, mp);
13210
13211   mp->sw_if_index = htonl (sw_if_index);
13212
13213   S (mp);
13214
13215   /* Use a control ping for synchronization */
13216   M (CONTROL_PING, mp_ping);
13217   S (mp_ping);
13218
13219   W (ret);
13220   return ret;
13221 }
13222
13223 static int
13224 api_gre_tunnel_add_del (vat_main_t * vam)
13225 {
13226   unformat_input_t *line_input = vam->input;
13227   vl_api_address_t src = { }, dst =
13228   {
13229   };
13230   vl_api_gre_tunnel_add_del_t *mp;
13231   vl_api_gre_tunnel_type_t t_type;
13232   u8 is_add = 1;
13233   u8 src_set = 0;
13234   u8 dst_set = 0;
13235   u32 outer_fib_id = 0;
13236   u32 session_id = 0;
13237   u32 instance = ~0;
13238   int ret;
13239
13240   t_type = GRE_API_TUNNEL_TYPE_L3;
13241
13242   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13243     {
13244       if (unformat (line_input, "del"))
13245         is_add = 0;
13246       else if (unformat (line_input, "instance %d", &instance))
13247         ;
13248       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13249         {
13250           src_set = 1;
13251         }
13252       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13253         {
13254           dst_set = 1;
13255         }
13256       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13257         ;
13258       else if (unformat (line_input, "teb"))
13259         t_type = GRE_API_TUNNEL_TYPE_TEB;
13260       else if (unformat (line_input, "erspan %d", &session_id))
13261         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13262       else
13263         {
13264           errmsg ("parse error '%U'", format_unformat_error, line_input);
13265           return -99;
13266         }
13267     }
13268
13269   if (src_set == 0)
13270     {
13271       errmsg ("tunnel src address not specified");
13272       return -99;
13273     }
13274   if (dst_set == 0)
13275     {
13276       errmsg ("tunnel dst address not specified");
13277       return -99;
13278     }
13279
13280   M (GRE_TUNNEL_ADD_DEL, mp);
13281
13282   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13283   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13284
13285   mp->tunnel.instance = htonl (instance);
13286   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13287   mp->is_add = is_add;
13288   mp->tunnel.session_id = htons ((u16) session_id);
13289   mp->tunnel.type = htonl (t_type);
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static void vl_api_gre_tunnel_details_t_handler
13297   (vl_api_gre_tunnel_details_t * mp)
13298 {
13299   vat_main_t *vam = &vat_main;
13300
13301   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13302          ntohl (mp->tunnel.sw_if_index),
13303          ntohl (mp->tunnel.instance),
13304          format_vl_api_address, &mp->tunnel.src,
13305          format_vl_api_address, &mp->tunnel.dst,
13306          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13307          ntohl (mp->tunnel.session_id));
13308 }
13309
13310 static void
13311 vat_json_object_add_address (vat_json_node_t * node,
13312                              const char *str, const vl_api_address_t * addr)
13313 {
13314   if (ADDRESS_IP6 == addr->af)
13315     {
13316       struct in6_addr ip6;
13317
13318       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13319       vat_json_object_add_ip6 (node, str, ip6);
13320     }
13321   else
13322     {
13323       struct in_addr ip4;
13324
13325       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13326       vat_json_object_add_ip4 (node, str, ip4);
13327     }
13328 }
13329
13330 static void vl_api_gre_tunnel_details_t_handler_json
13331   (vl_api_gre_tunnel_details_t * mp)
13332 {
13333   vat_main_t *vam = &vat_main;
13334   vat_json_node_t *node = NULL;
13335
13336   if (VAT_JSON_ARRAY != vam->json_tree.type)
13337     {
13338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13339       vat_json_init_array (&vam->json_tree);
13340     }
13341   node = vat_json_array_add (&vam->json_tree);
13342
13343   vat_json_init_object (node);
13344   vat_json_object_add_uint (node, "sw_if_index",
13345                             ntohl (mp->tunnel.sw_if_index));
13346   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13347
13348   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13349   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13350   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13351   vat_json_object_add_uint (node, "outer_fib_id",
13352                             ntohl (mp->tunnel.outer_fib_id));
13353   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13354 }
13355
13356 static int
13357 api_gre_tunnel_dump (vat_main_t * vam)
13358 {
13359   unformat_input_t *i = vam->input;
13360   vl_api_gre_tunnel_dump_t *mp;
13361   vl_api_control_ping_t *mp_ping;
13362   u32 sw_if_index;
13363   u8 sw_if_index_set = 0;
13364   int ret;
13365
13366   /* Parse args required to build the message */
13367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13368     {
13369       if (unformat (i, "sw_if_index %d", &sw_if_index))
13370         sw_if_index_set = 1;
13371       else
13372         break;
13373     }
13374
13375   if (sw_if_index_set == 0)
13376     {
13377       sw_if_index = ~0;
13378     }
13379
13380   if (!vam->json_output)
13381     {
13382       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13383              "sw_if_index", "instance", "src_address", "dst_address",
13384              "tunnel_type", "outer_fib_id", "session_id");
13385     }
13386
13387   /* Get list of gre-tunnel interfaces */
13388   M (GRE_TUNNEL_DUMP, mp);
13389
13390   mp->sw_if_index = htonl (sw_if_index);
13391
13392   S (mp);
13393
13394   /* Use a control ping for synchronization */
13395   MPING (CONTROL_PING, mp_ping);
13396   S (mp_ping);
13397
13398   W (ret);
13399   return ret;
13400 }
13401
13402 static int
13403 api_l2_fib_clear_table (vat_main_t * vam)
13404 {
13405 //  unformat_input_t * i = vam->input;
13406   vl_api_l2_fib_clear_table_t *mp;
13407   int ret;
13408
13409   M (L2_FIB_CLEAR_TABLE, mp);
13410
13411   S (mp);
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static int
13417 api_l2_interface_efp_filter (vat_main_t * vam)
13418 {
13419   unformat_input_t *i = vam->input;
13420   vl_api_l2_interface_efp_filter_t *mp;
13421   u32 sw_if_index;
13422   u8 enable = 1;
13423   u8 sw_if_index_set = 0;
13424   int ret;
13425
13426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13427     {
13428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13429         sw_if_index_set = 1;
13430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13431         sw_if_index_set = 1;
13432       else if (unformat (i, "enable"))
13433         enable = 1;
13434       else if (unformat (i, "disable"))
13435         enable = 0;
13436       else
13437         {
13438           clib_warning ("parse error '%U'", format_unformat_error, i);
13439           return -99;
13440         }
13441     }
13442
13443   if (sw_if_index_set == 0)
13444     {
13445       errmsg ("missing sw_if_index");
13446       return -99;
13447     }
13448
13449   M (L2_INTERFACE_EFP_FILTER, mp);
13450
13451   mp->sw_if_index = ntohl (sw_if_index);
13452   mp->enable_disable = enable;
13453
13454   S (mp);
13455   W (ret);
13456   return ret;
13457 }
13458
13459 #define foreach_vtr_op                          \
13460 _("disable",  L2_VTR_DISABLED)                  \
13461 _("push-1",  L2_VTR_PUSH_1)                     \
13462 _("push-2",  L2_VTR_PUSH_2)                     \
13463 _("pop-1",  L2_VTR_POP_1)                       \
13464 _("pop-2",  L2_VTR_POP_2)                       \
13465 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13466 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13467 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13468 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13469
13470 static int
13471 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13472 {
13473   unformat_input_t *i = vam->input;
13474   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13475   u32 sw_if_index;
13476   u8 sw_if_index_set = 0;
13477   u8 vtr_op_set = 0;
13478   u32 vtr_op = 0;
13479   u32 push_dot1q = 1;
13480   u32 tag1 = ~0;
13481   u32 tag2 = ~0;
13482   int ret;
13483
13484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13485     {
13486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13487         sw_if_index_set = 1;
13488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13489         sw_if_index_set = 1;
13490       else if (unformat (i, "vtr_op %d", &vtr_op))
13491         vtr_op_set = 1;
13492 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13493       foreach_vtr_op
13494 #undef _
13495         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13496         ;
13497       else if (unformat (i, "tag1 %d", &tag1))
13498         ;
13499       else if (unformat (i, "tag2 %d", &tag2))
13500         ;
13501       else
13502         {
13503           clib_warning ("parse error '%U'", format_unformat_error, i);
13504           return -99;
13505         }
13506     }
13507
13508   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13509     {
13510       errmsg ("missing vtr operation or sw_if_index");
13511       return -99;
13512     }
13513
13514   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13515   mp->sw_if_index = ntohl (sw_if_index);
13516   mp->vtr_op = ntohl (vtr_op);
13517   mp->push_dot1q = ntohl (push_dot1q);
13518   mp->tag1 = ntohl (tag1);
13519   mp->tag2 = ntohl (tag2);
13520
13521   S (mp);
13522   W (ret);
13523   return ret;
13524 }
13525
13526 static int
13527 api_create_vhost_user_if (vat_main_t * vam)
13528 {
13529   unformat_input_t *i = vam->input;
13530   vl_api_create_vhost_user_if_t *mp;
13531   u8 *file_name;
13532   u8 is_server = 0;
13533   u8 file_name_set = 0;
13534   u32 custom_dev_instance = ~0;
13535   u8 hwaddr[6];
13536   u8 use_custom_mac = 0;
13537   u8 disable_mrg_rxbuf = 0;
13538   u8 disable_indirect_desc = 0;
13539   u8 *tag = 0;
13540   int ret;
13541
13542   /* Shut up coverity */
13543   clib_memset (hwaddr, 0, sizeof (hwaddr));
13544
13545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13546     {
13547       if (unformat (i, "socket %s", &file_name))
13548         {
13549           file_name_set = 1;
13550         }
13551       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13552         ;
13553       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13554         use_custom_mac = 1;
13555       else if (unformat (i, "server"))
13556         is_server = 1;
13557       else if (unformat (i, "disable_mrg_rxbuf"))
13558         disable_mrg_rxbuf = 1;
13559       else if (unformat (i, "disable_indirect_desc"))
13560         disable_indirect_desc = 1;
13561       else if (unformat (i, "tag %s", &tag))
13562         ;
13563       else
13564         break;
13565     }
13566
13567   if (file_name_set == 0)
13568     {
13569       errmsg ("missing socket file name");
13570       return -99;
13571     }
13572
13573   if (vec_len (file_name) > 255)
13574     {
13575       errmsg ("socket file name too long");
13576       return -99;
13577     }
13578   vec_add1 (file_name, 0);
13579
13580   M (CREATE_VHOST_USER_IF, mp);
13581
13582   mp->is_server = is_server;
13583   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13584   mp->disable_indirect_desc = disable_indirect_desc;
13585   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13586   vec_free (file_name);
13587   if (custom_dev_instance != ~0)
13588     {
13589       mp->renumber = 1;
13590       mp->custom_dev_instance = ntohl (custom_dev_instance);
13591     }
13592
13593   mp->use_custom_mac = use_custom_mac;
13594   clib_memcpy (mp->mac_address, hwaddr, 6);
13595   if (tag)
13596     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13597   vec_free (tag);
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_modify_vhost_user_if (vat_main_t * vam)
13606 {
13607   unformat_input_t *i = vam->input;
13608   vl_api_modify_vhost_user_if_t *mp;
13609   u8 *file_name;
13610   u8 is_server = 0;
13611   u8 file_name_set = 0;
13612   u32 custom_dev_instance = ~0;
13613   u8 sw_if_index_set = 0;
13614   u32 sw_if_index = (u32) ~ 0;
13615   int ret;
13616
13617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13618     {
13619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13620         sw_if_index_set = 1;
13621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13622         sw_if_index_set = 1;
13623       else if (unformat (i, "socket %s", &file_name))
13624         {
13625           file_name_set = 1;
13626         }
13627       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13628         ;
13629       else if (unformat (i, "server"))
13630         is_server = 1;
13631       else
13632         break;
13633     }
13634
13635   if (sw_if_index_set == 0)
13636     {
13637       errmsg ("missing sw_if_index or interface name");
13638       return -99;
13639     }
13640
13641   if (file_name_set == 0)
13642     {
13643       errmsg ("missing socket file name");
13644       return -99;
13645     }
13646
13647   if (vec_len (file_name) > 255)
13648     {
13649       errmsg ("socket file name too long");
13650       return -99;
13651     }
13652   vec_add1 (file_name, 0);
13653
13654   M (MODIFY_VHOST_USER_IF, mp);
13655
13656   mp->sw_if_index = ntohl (sw_if_index);
13657   mp->is_server = is_server;
13658   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13659   vec_free (file_name);
13660   if (custom_dev_instance != ~0)
13661     {
13662       mp->renumber = 1;
13663       mp->custom_dev_instance = ntohl (custom_dev_instance);
13664     }
13665
13666   S (mp);
13667   W (ret);
13668   return ret;
13669 }
13670
13671 static int
13672 api_delete_vhost_user_if (vat_main_t * vam)
13673 {
13674   unformat_input_t *i = vam->input;
13675   vl_api_delete_vhost_user_if_t *mp;
13676   u32 sw_if_index = ~0;
13677   u8 sw_if_index_set = 0;
13678   int ret;
13679
13680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13681     {
13682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13683         sw_if_index_set = 1;
13684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13685         sw_if_index_set = 1;
13686       else
13687         break;
13688     }
13689
13690   if (sw_if_index_set == 0)
13691     {
13692       errmsg ("missing sw_if_index or interface name");
13693       return -99;
13694     }
13695
13696
13697   M (DELETE_VHOST_USER_IF, mp);
13698
13699   mp->sw_if_index = ntohl (sw_if_index);
13700
13701   S (mp);
13702   W (ret);
13703   return ret;
13704 }
13705
13706 static void vl_api_sw_interface_vhost_user_details_t_handler
13707   (vl_api_sw_interface_vhost_user_details_t * mp)
13708 {
13709   vat_main_t *vam = &vat_main;
13710
13711   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13712          (char *) mp->interface_name,
13713          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13714          clib_net_to_host_u64 (mp->features), mp->is_server,
13715          ntohl (mp->num_regions), (char *) mp->sock_filename);
13716   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13717 }
13718
13719 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13720   (vl_api_sw_interface_vhost_user_details_t * mp)
13721 {
13722   vat_main_t *vam = &vat_main;
13723   vat_json_node_t *node = NULL;
13724
13725   if (VAT_JSON_ARRAY != vam->json_tree.type)
13726     {
13727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13728       vat_json_init_array (&vam->json_tree);
13729     }
13730   node = vat_json_array_add (&vam->json_tree);
13731
13732   vat_json_init_object (node);
13733   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13734   vat_json_object_add_string_copy (node, "interface_name",
13735                                    mp->interface_name);
13736   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13737                             ntohl (mp->virtio_net_hdr_sz));
13738   vat_json_object_add_uint (node, "features",
13739                             clib_net_to_host_u64 (mp->features));
13740   vat_json_object_add_uint (node, "is_server", mp->is_server);
13741   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13742   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13743   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13744 }
13745
13746 static int
13747 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13748 {
13749   vl_api_sw_interface_vhost_user_dump_t *mp;
13750   vl_api_control_ping_t *mp_ping;
13751   int ret;
13752   print (vam->ofp,
13753          "Interface name            idx hdr_sz features server regions filename");
13754
13755   /* Get list of vhost-user interfaces */
13756   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13757   S (mp);
13758
13759   /* Use a control ping for synchronization */
13760   MPING (CONTROL_PING, mp_ping);
13761   S (mp_ping);
13762
13763   W (ret);
13764   return ret;
13765 }
13766
13767 static int
13768 api_show_version (vat_main_t * vam)
13769 {
13770   vl_api_show_version_t *mp;
13771   int ret;
13772
13773   M (SHOW_VERSION, mp);
13774
13775   S (mp);
13776   W (ret);
13777   return ret;
13778 }
13779
13780
13781 static int
13782 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13783 {
13784   unformat_input_t *line_input = vam->input;
13785   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13786   ip4_address_t local4, remote4;
13787   ip6_address_t local6, remote6;
13788   u8 is_add = 1;
13789   u8 ipv4_set = 0, ipv6_set = 0;
13790   u8 local_set = 0;
13791   u8 remote_set = 0;
13792   u8 grp_set = 0;
13793   u32 mcast_sw_if_index = ~0;
13794   u32 encap_vrf_id = 0;
13795   u32 decap_vrf_id = 0;
13796   u8 protocol = ~0;
13797   u32 vni;
13798   u8 vni_set = 0;
13799   int ret;
13800
13801   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13802   clib_memset (&local4, 0, sizeof local4);
13803   clib_memset (&remote4, 0, sizeof remote4);
13804   clib_memset (&local6, 0, sizeof local6);
13805   clib_memset (&remote6, 0, sizeof remote6);
13806
13807   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (line_input, "del"))
13810         is_add = 0;
13811       else if (unformat (line_input, "local %U",
13812                          unformat_ip4_address, &local4))
13813         {
13814           local_set = 1;
13815           ipv4_set = 1;
13816         }
13817       else if (unformat (line_input, "remote %U",
13818                          unformat_ip4_address, &remote4))
13819         {
13820           remote_set = 1;
13821           ipv4_set = 1;
13822         }
13823       else if (unformat (line_input, "local %U",
13824                          unformat_ip6_address, &local6))
13825         {
13826           local_set = 1;
13827           ipv6_set = 1;
13828         }
13829       else if (unformat (line_input, "remote %U",
13830                          unformat_ip6_address, &remote6))
13831         {
13832           remote_set = 1;
13833           ipv6_set = 1;
13834         }
13835       else if (unformat (line_input, "group %U %U",
13836                          unformat_ip4_address, &remote4,
13837                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13838         {
13839           grp_set = remote_set = 1;
13840           ipv4_set = 1;
13841         }
13842       else if (unformat (line_input, "group %U",
13843                          unformat_ip4_address, &remote4))
13844         {
13845           grp_set = remote_set = 1;
13846           ipv4_set = 1;
13847         }
13848       else if (unformat (line_input, "group %U %U",
13849                          unformat_ip6_address, &remote6,
13850                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13851         {
13852           grp_set = remote_set = 1;
13853           ipv6_set = 1;
13854         }
13855       else if (unformat (line_input, "group %U",
13856                          unformat_ip6_address, &remote6))
13857         {
13858           grp_set = remote_set = 1;
13859           ipv6_set = 1;
13860         }
13861       else
13862         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13863         ;
13864       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13865         ;
13866       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13867         ;
13868       else if (unformat (line_input, "vni %d", &vni))
13869         vni_set = 1;
13870       else if (unformat (line_input, "next-ip4"))
13871         protocol = 1;
13872       else if (unformat (line_input, "next-ip6"))
13873         protocol = 2;
13874       else if (unformat (line_input, "next-ethernet"))
13875         protocol = 3;
13876       else if (unformat (line_input, "next-nsh"))
13877         protocol = 4;
13878       else
13879         {
13880           errmsg ("parse error '%U'", format_unformat_error, line_input);
13881           return -99;
13882         }
13883     }
13884
13885   if (local_set == 0)
13886     {
13887       errmsg ("tunnel local address not specified");
13888       return -99;
13889     }
13890   if (remote_set == 0)
13891     {
13892       errmsg ("tunnel remote address not specified");
13893       return -99;
13894     }
13895   if (grp_set && mcast_sw_if_index == ~0)
13896     {
13897       errmsg ("tunnel nonexistent multicast device");
13898       return -99;
13899     }
13900   if (ipv4_set && ipv6_set)
13901     {
13902       errmsg ("both IPv4 and IPv6 addresses specified");
13903       return -99;
13904     }
13905
13906   if (vni_set == 0)
13907     {
13908       errmsg ("vni not specified");
13909       return -99;
13910     }
13911
13912   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13913
13914
13915   if (ipv6_set)
13916     {
13917       clib_memcpy (&mp->local, &local6, sizeof (local6));
13918       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13919     }
13920   else
13921     {
13922       clib_memcpy (&mp->local, &local4, sizeof (local4));
13923       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13924     }
13925
13926   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13927   mp->encap_vrf_id = ntohl (encap_vrf_id);
13928   mp->decap_vrf_id = ntohl (decap_vrf_id);
13929   mp->protocol = protocol;
13930   mp->vni = ntohl (vni);
13931   mp->is_add = is_add;
13932   mp->is_ipv6 = ipv6_set;
13933
13934   S (mp);
13935   W (ret);
13936   return ret;
13937 }
13938
13939 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13940   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13941 {
13942   vat_main_t *vam = &vat_main;
13943   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13944   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13945
13946   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13947          ntohl (mp->sw_if_index),
13948          format_ip46_address, &local, IP46_TYPE_ANY,
13949          format_ip46_address, &remote, IP46_TYPE_ANY,
13950          ntohl (mp->vni), mp->protocol,
13951          ntohl (mp->mcast_sw_if_index),
13952          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13953 }
13954
13955
13956 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13957   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13958 {
13959   vat_main_t *vam = &vat_main;
13960   vat_json_node_t *node = NULL;
13961   struct in_addr ip4;
13962   struct in6_addr ip6;
13963
13964   if (VAT_JSON_ARRAY != vam->json_tree.type)
13965     {
13966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13967       vat_json_init_array (&vam->json_tree);
13968     }
13969   node = vat_json_array_add (&vam->json_tree);
13970
13971   vat_json_init_object (node);
13972   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13973   if (mp->is_ipv6)
13974     {
13975       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13976       vat_json_object_add_ip6 (node, "local", ip6);
13977       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13978       vat_json_object_add_ip6 (node, "remote", ip6);
13979     }
13980   else
13981     {
13982       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13983       vat_json_object_add_ip4 (node, "local", ip4);
13984       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13985       vat_json_object_add_ip4 (node, "remote", ip4);
13986     }
13987   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13988   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13989   vat_json_object_add_uint (node, "mcast_sw_if_index",
13990                             ntohl (mp->mcast_sw_if_index));
13991   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13992   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13993   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13994 }
13995
13996 static int
13997 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13998 {
13999   unformat_input_t *i = vam->input;
14000   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14001   vl_api_control_ping_t *mp_ping;
14002   u32 sw_if_index;
14003   u8 sw_if_index_set = 0;
14004   int ret;
14005
14006   /* Parse args required to build the message */
14007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (i, "sw_if_index %d", &sw_if_index))
14010         sw_if_index_set = 1;
14011       else
14012         break;
14013     }
14014
14015   if (sw_if_index_set == 0)
14016     {
14017       sw_if_index = ~0;
14018     }
14019
14020   if (!vam->json_output)
14021     {
14022       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14023              "sw_if_index", "local", "remote", "vni",
14024              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14025     }
14026
14027   /* Get list of vxlan-tunnel interfaces */
14028   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14029
14030   mp->sw_if_index = htonl (sw_if_index);
14031
14032   S (mp);
14033
14034   /* Use a control ping for synchronization */
14035   MPING (CONTROL_PING, mp_ping);
14036   S (mp_ping);
14037
14038   W (ret);
14039   return ret;
14040 }
14041
14042 static void vl_api_l2_fib_table_details_t_handler
14043   (vl_api_l2_fib_table_details_t * mp)
14044 {
14045   vat_main_t *vam = &vat_main;
14046
14047   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14048          "       %d       %d     %d",
14049          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14050          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14051          mp->bvi_mac);
14052 }
14053
14054 static void vl_api_l2_fib_table_details_t_handler_json
14055   (vl_api_l2_fib_table_details_t * mp)
14056 {
14057   vat_main_t *vam = &vat_main;
14058   vat_json_node_t *node = NULL;
14059
14060   if (VAT_JSON_ARRAY != vam->json_tree.type)
14061     {
14062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14063       vat_json_init_array (&vam->json_tree);
14064     }
14065   node = vat_json_array_add (&vam->json_tree);
14066
14067   vat_json_init_object (node);
14068   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14069   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14070   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14071   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14072   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14073   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14074 }
14075
14076 static int
14077 api_l2_fib_table_dump (vat_main_t * vam)
14078 {
14079   unformat_input_t *i = vam->input;
14080   vl_api_l2_fib_table_dump_t *mp;
14081   vl_api_control_ping_t *mp_ping;
14082   u32 bd_id;
14083   u8 bd_id_set = 0;
14084   int ret;
14085
14086   /* Parse args required to build the message */
14087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14088     {
14089       if (unformat (i, "bd_id %d", &bd_id))
14090         bd_id_set = 1;
14091       else
14092         break;
14093     }
14094
14095   if (bd_id_set == 0)
14096     {
14097       errmsg ("missing bridge domain");
14098       return -99;
14099     }
14100
14101   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14102
14103   /* Get list of l2 fib entries */
14104   M (L2_FIB_TABLE_DUMP, mp);
14105
14106   mp->bd_id = ntohl (bd_id);
14107   S (mp);
14108
14109   /* Use a control ping for synchronization */
14110   MPING (CONTROL_PING, mp_ping);
14111   S (mp_ping);
14112
14113   W (ret);
14114   return ret;
14115 }
14116
14117
14118 static int
14119 api_interface_name_renumber (vat_main_t * vam)
14120 {
14121   unformat_input_t *line_input = vam->input;
14122   vl_api_interface_name_renumber_t *mp;
14123   u32 sw_if_index = ~0;
14124   u32 new_show_dev_instance = ~0;
14125   int ret;
14126
14127   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14128     {
14129       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14130                     &sw_if_index))
14131         ;
14132       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14133         ;
14134       else if (unformat (line_input, "new_show_dev_instance %d",
14135                          &new_show_dev_instance))
14136         ;
14137       else
14138         break;
14139     }
14140
14141   if (sw_if_index == ~0)
14142     {
14143       errmsg ("missing interface name or sw_if_index");
14144       return -99;
14145     }
14146
14147   if (new_show_dev_instance == ~0)
14148     {
14149       errmsg ("missing new_show_dev_instance");
14150       return -99;
14151     }
14152
14153   M (INTERFACE_NAME_RENUMBER, mp);
14154
14155   mp->sw_if_index = ntohl (sw_if_index);
14156   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14157
14158   S (mp);
14159   W (ret);
14160   return ret;
14161 }
14162
14163 static int
14164 api_ip_probe_neighbor (vat_main_t * vam)
14165 {
14166   unformat_input_t *i = vam->input;
14167   vl_api_ip_probe_neighbor_t *mp;
14168   vl_api_address_t dst_adr = { };
14169   u8 int_set = 0;
14170   u8 adr_set = 0;
14171   u32 sw_if_index;
14172   int ret;
14173
14174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14175     {
14176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14177         int_set = 1;
14178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14179         int_set = 1;
14180       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
14181         adr_set = 1;
14182       else
14183         break;
14184     }
14185
14186   if (int_set == 0)
14187     {
14188       errmsg ("missing interface");
14189       return -99;
14190     }
14191
14192   if (adr_set == 0)
14193     {
14194       errmsg ("missing addresses");
14195       return -99;
14196     }
14197
14198   M (IP_PROBE_NEIGHBOR, mp);
14199
14200   mp->sw_if_index = ntohl (sw_if_index);
14201   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14202
14203   S (mp);
14204   W (ret);
14205   return ret;
14206 }
14207
14208 static int
14209 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14210 {
14211   unformat_input_t *i = vam->input;
14212   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14213   u8 mode = IP_SCAN_V46_NEIGHBORS;
14214   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14215   int ret;
14216
14217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14218     {
14219       if (unformat (i, "ip4"))
14220         mode = IP_SCAN_V4_NEIGHBORS;
14221       else if (unformat (i, "ip6"))
14222         mode = IP_SCAN_V6_NEIGHBORS;
14223       if (unformat (i, "both"))
14224         mode = IP_SCAN_V46_NEIGHBORS;
14225       else if (unformat (i, "disable"))
14226         mode = IP_SCAN_DISABLED;
14227       else if (unformat (i, "interval %d", &interval))
14228         ;
14229       else if (unformat (i, "max-time %d", &time))
14230         ;
14231       else if (unformat (i, "max-update %d", &update))
14232         ;
14233       else if (unformat (i, "delay %d", &delay))
14234         ;
14235       else if (unformat (i, "stale %d", &stale))
14236         ;
14237       else
14238         break;
14239     }
14240
14241   if (interval > 255)
14242     {
14243       errmsg ("interval cannot exceed 255 minutes.");
14244       return -99;
14245     }
14246   if (time > 255)
14247     {
14248       errmsg ("max-time cannot exceed 255 usec.");
14249       return -99;
14250     }
14251   if (update > 255)
14252     {
14253       errmsg ("max-update cannot exceed 255.");
14254       return -99;
14255     }
14256   if (delay > 255)
14257     {
14258       errmsg ("delay cannot exceed 255 msec.");
14259       return -99;
14260     }
14261   if (stale > 255)
14262     {
14263       errmsg ("stale cannot exceed 255 minutes.");
14264       return -99;
14265     }
14266
14267   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14268   mp->mode = mode;
14269   mp->scan_interval = interval;
14270   mp->max_proc_time = time;
14271   mp->max_update = update;
14272   mp->scan_int_delay = delay;
14273   mp->stale_threshold = stale;
14274
14275   S (mp);
14276   W (ret);
14277   return ret;
14278 }
14279
14280 static int
14281 api_want_ip4_arp_events (vat_main_t * vam)
14282 {
14283   unformat_input_t *line_input = vam->input;
14284   vl_api_want_ip4_arp_events_t *mp;
14285   ip4_address_t address;
14286   int address_set = 0;
14287   u32 enable_disable = 1;
14288   int ret;
14289
14290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14293         address_set = 1;
14294       else if (unformat (line_input, "del"))
14295         enable_disable = 0;
14296       else
14297         break;
14298     }
14299
14300   if (address_set == 0)
14301     {
14302       errmsg ("missing addresses");
14303       return -99;
14304     }
14305
14306   M (WANT_IP4_ARP_EVENTS, mp);
14307   mp->enable_disable = enable_disable;
14308   mp->pid = htonl (getpid ());
14309   clib_memcpy (mp->ip, &address, sizeof (address));
14310
14311   S (mp);
14312   W (ret);
14313   return ret;
14314 }
14315
14316 static int
14317 api_want_ip6_nd_events (vat_main_t * vam)
14318 {
14319   unformat_input_t *line_input = vam->input;
14320   vl_api_want_ip6_nd_events_t *mp;
14321   vl_api_ip6_address_t address;
14322   int address_set = 0;
14323   u32 enable_disable = 1;
14324   int ret;
14325
14326   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14327     {
14328       if (unformat
14329           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14330         address_set = 1;
14331       else if (unformat (line_input, "del"))
14332         enable_disable = 0;
14333       else
14334         break;
14335     }
14336
14337   if (address_set == 0)
14338     {
14339       errmsg ("missing addresses");
14340       return -99;
14341     }
14342
14343   M (WANT_IP6_ND_EVENTS, mp);
14344   mp->enable_disable = enable_disable;
14345   mp->pid = htonl (getpid ());
14346   clib_memcpy (&mp->ip, &address, sizeof (address));
14347
14348   S (mp);
14349   W (ret);
14350   return ret;
14351 }
14352
14353 static int
14354 api_want_l2_macs_events (vat_main_t * vam)
14355 {
14356   unformat_input_t *line_input = vam->input;
14357   vl_api_want_l2_macs_events_t *mp;
14358   u8 enable_disable = 1;
14359   u32 scan_delay = 0;
14360   u32 max_macs_in_event = 0;
14361   u32 learn_limit = 0;
14362   int ret;
14363
14364   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14365     {
14366       if (unformat (line_input, "learn-limit %d", &learn_limit))
14367         ;
14368       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14369         ;
14370       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14371         ;
14372       else if (unformat (line_input, "disable"))
14373         enable_disable = 0;
14374       else
14375         break;
14376     }
14377
14378   M (WANT_L2_MACS_EVENTS, mp);
14379   mp->enable_disable = enable_disable;
14380   mp->pid = htonl (getpid ());
14381   mp->learn_limit = htonl (learn_limit);
14382   mp->scan_delay = (u8) scan_delay;
14383   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14384   S (mp);
14385   W (ret);
14386   return ret;
14387 }
14388
14389 static int
14390 api_input_acl_set_interface (vat_main_t * vam)
14391 {
14392   unformat_input_t *i = vam->input;
14393   vl_api_input_acl_set_interface_t *mp;
14394   u32 sw_if_index;
14395   int sw_if_index_set;
14396   u32 ip4_table_index = ~0;
14397   u32 ip6_table_index = ~0;
14398   u32 l2_table_index = ~0;
14399   u8 is_add = 1;
14400   int ret;
14401
14402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14403     {
14404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14405         sw_if_index_set = 1;
14406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14407         sw_if_index_set = 1;
14408       else if (unformat (i, "del"))
14409         is_add = 0;
14410       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14411         ;
14412       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14413         ;
14414       else if (unformat (i, "l2-table %d", &l2_table_index))
14415         ;
14416       else
14417         {
14418           clib_warning ("parse error '%U'", format_unformat_error, i);
14419           return -99;
14420         }
14421     }
14422
14423   if (sw_if_index_set == 0)
14424     {
14425       errmsg ("missing interface name or sw_if_index");
14426       return -99;
14427     }
14428
14429   M (INPUT_ACL_SET_INTERFACE, mp);
14430
14431   mp->sw_if_index = ntohl (sw_if_index);
14432   mp->ip4_table_index = ntohl (ip4_table_index);
14433   mp->ip6_table_index = ntohl (ip6_table_index);
14434   mp->l2_table_index = ntohl (l2_table_index);
14435   mp->is_add = is_add;
14436
14437   S (mp);
14438   W (ret);
14439   return ret;
14440 }
14441
14442 static int
14443 api_output_acl_set_interface (vat_main_t * vam)
14444 {
14445   unformat_input_t *i = vam->input;
14446   vl_api_output_acl_set_interface_t *mp;
14447   u32 sw_if_index;
14448   int sw_if_index_set;
14449   u32 ip4_table_index = ~0;
14450   u32 ip6_table_index = ~0;
14451   u32 l2_table_index = ~0;
14452   u8 is_add = 1;
14453   int ret;
14454
14455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14456     {
14457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14458         sw_if_index_set = 1;
14459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14460         sw_if_index_set = 1;
14461       else if (unformat (i, "del"))
14462         is_add = 0;
14463       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14464         ;
14465       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14466         ;
14467       else if (unformat (i, "l2-table %d", &l2_table_index))
14468         ;
14469       else
14470         {
14471           clib_warning ("parse error '%U'", format_unformat_error, i);
14472           return -99;
14473         }
14474     }
14475
14476   if (sw_if_index_set == 0)
14477     {
14478       errmsg ("missing interface name or sw_if_index");
14479       return -99;
14480     }
14481
14482   M (OUTPUT_ACL_SET_INTERFACE, mp);
14483
14484   mp->sw_if_index = ntohl (sw_if_index);
14485   mp->ip4_table_index = ntohl (ip4_table_index);
14486   mp->ip6_table_index = ntohl (ip6_table_index);
14487   mp->l2_table_index = ntohl (l2_table_index);
14488   mp->is_add = is_add;
14489
14490   S (mp);
14491   W (ret);
14492   return ret;
14493 }
14494
14495 static int
14496 api_ip_address_dump (vat_main_t * vam)
14497 {
14498   unformat_input_t *i = vam->input;
14499   vl_api_ip_address_dump_t *mp;
14500   vl_api_control_ping_t *mp_ping;
14501   u32 sw_if_index = ~0;
14502   u8 sw_if_index_set = 0;
14503   u8 ipv4_set = 0;
14504   u8 ipv6_set = 0;
14505   int ret;
14506
14507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14508     {
14509       if (unformat (i, "sw_if_index %d", &sw_if_index))
14510         sw_if_index_set = 1;
14511       else
14512         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14513         sw_if_index_set = 1;
14514       else if (unformat (i, "ipv4"))
14515         ipv4_set = 1;
14516       else if (unformat (i, "ipv6"))
14517         ipv6_set = 1;
14518       else
14519         break;
14520     }
14521
14522   if (ipv4_set && ipv6_set)
14523     {
14524       errmsg ("ipv4 and ipv6 flags cannot be both set");
14525       return -99;
14526     }
14527
14528   if ((!ipv4_set) && (!ipv6_set))
14529     {
14530       errmsg ("no ipv4 nor ipv6 flag set");
14531       return -99;
14532     }
14533
14534   if (sw_if_index_set == 0)
14535     {
14536       errmsg ("missing interface name or sw_if_index");
14537       return -99;
14538     }
14539
14540   vam->current_sw_if_index = sw_if_index;
14541   vam->is_ipv6 = ipv6_set;
14542
14543   M (IP_ADDRESS_DUMP, mp);
14544   mp->sw_if_index = ntohl (sw_if_index);
14545   mp->is_ipv6 = ipv6_set;
14546   S (mp);
14547
14548   /* Use a control ping for synchronization */
14549   MPING (CONTROL_PING, mp_ping);
14550   S (mp_ping);
14551
14552   W (ret);
14553   return ret;
14554 }
14555
14556 static int
14557 api_ip_dump (vat_main_t * vam)
14558 {
14559   vl_api_ip_dump_t *mp;
14560   vl_api_control_ping_t *mp_ping;
14561   unformat_input_t *in = vam->input;
14562   int ipv4_set = 0;
14563   int ipv6_set = 0;
14564   int is_ipv6;
14565   int i;
14566   int ret;
14567
14568   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14569     {
14570       if (unformat (in, "ipv4"))
14571         ipv4_set = 1;
14572       else if (unformat (in, "ipv6"))
14573         ipv6_set = 1;
14574       else
14575         break;
14576     }
14577
14578   if (ipv4_set && ipv6_set)
14579     {
14580       errmsg ("ipv4 and ipv6 flags cannot be both set");
14581       return -99;
14582     }
14583
14584   if ((!ipv4_set) && (!ipv6_set))
14585     {
14586       errmsg ("no ipv4 nor ipv6 flag set");
14587       return -99;
14588     }
14589
14590   is_ipv6 = ipv6_set;
14591   vam->is_ipv6 = is_ipv6;
14592
14593   /* free old data */
14594   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14595     {
14596       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14597     }
14598   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14599
14600   M (IP_DUMP, mp);
14601   mp->is_ipv6 = ipv6_set;
14602   S (mp);
14603
14604   /* Use a control ping for synchronization */
14605   MPING (CONTROL_PING, mp_ping);
14606   S (mp_ping);
14607
14608   W (ret);
14609   return ret;
14610 }
14611
14612 static int
14613 api_ipsec_spd_add_del (vat_main_t * vam)
14614 {
14615   unformat_input_t *i = vam->input;
14616   vl_api_ipsec_spd_add_del_t *mp;
14617   u32 spd_id = ~0;
14618   u8 is_add = 1;
14619   int ret;
14620
14621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14622     {
14623       if (unformat (i, "spd_id %d", &spd_id))
14624         ;
14625       else if (unformat (i, "del"))
14626         is_add = 0;
14627       else
14628         {
14629           clib_warning ("parse error '%U'", format_unformat_error, i);
14630           return -99;
14631         }
14632     }
14633   if (spd_id == ~0)
14634     {
14635       errmsg ("spd_id must be set");
14636       return -99;
14637     }
14638
14639   M (IPSEC_SPD_ADD_DEL, mp);
14640
14641   mp->spd_id = ntohl (spd_id);
14642   mp->is_add = is_add;
14643
14644   S (mp);
14645   W (ret);
14646   return ret;
14647 }
14648
14649 static int
14650 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14651 {
14652   unformat_input_t *i = vam->input;
14653   vl_api_ipsec_interface_add_del_spd_t *mp;
14654   u32 sw_if_index;
14655   u8 sw_if_index_set = 0;
14656   u32 spd_id = (u32) ~ 0;
14657   u8 is_add = 1;
14658   int ret;
14659
14660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14661     {
14662       if (unformat (i, "del"))
14663         is_add = 0;
14664       else if (unformat (i, "spd_id %d", &spd_id))
14665         ;
14666       else
14667         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14668         sw_if_index_set = 1;
14669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14670         sw_if_index_set = 1;
14671       else
14672         {
14673           clib_warning ("parse error '%U'", format_unformat_error, i);
14674           return -99;
14675         }
14676
14677     }
14678
14679   if (spd_id == (u32) ~ 0)
14680     {
14681       errmsg ("spd_id must be set");
14682       return -99;
14683     }
14684
14685   if (sw_if_index_set == 0)
14686     {
14687       errmsg ("missing interface name or sw_if_index");
14688       return -99;
14689     }
14690
14691   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14692
14693   mp->spd_id = ntohl (spd_id);
14694   mp->sw_if_index = ntohl (sw_if_index);
14695   mp->is_add = is_add;
14696
14697   S (mp);
14698   W (ret);
14699   return ret;
14700 }
14701
14702 static int
14703 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14704 {
14705   unformat_input_t *i = vam->input;
14706   vl_api_ipsec_spd_entry_add_del_t *mp;
14707   u8 is_add = 1, is_outbound = 0;
14708   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14709   i32 priority = 0;
14710   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14711   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14712   vl_api_address_t laddr_start = { }, laddr_stop =
14713   {
14714   }, raddr_start =
14715   {
14716   }, raddr_stop =
14717   {
14718   };
14719   int ret;
14720
14721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (i, "del"))
14724         is_add = 0;
14725       if (unformat (i, "outbound"))
14726         is_outbound = 1;
14727       if (unformat (i, "inbound"))
14728         is_outbound = 0;
14729       else if (unformat (i, "spd_id %d", &spd_id))
14730         ;
14731       else if (unformat (i, "sa_id %d", &sa_id))
14732         ;
14733       else if (unformat (i, "priority %d", &priority))
14734         ;
14735       else if (unformat (i, "protocol %d", &protocol))
14736         ;
14737       else if (unformat (i, "lport_start %d", &lport_start))
14738         ;
14739       else if (unformat (i, "lport_stop %d", &lport_stop))
14740         ;
14741       else if (unformat (i, "rport_start %d", &rport_start))
14742         ;
14743       else if (unformat (i, "rport_stop %d", &rport_stop))
14744         ;
14745       else if (unformat (i, "laddr_start %U",
14746                          unformat_vl_api_address, &laddr_start))
14747         ;
14748       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14749                          &laddr_stop))
14750         ;
14751       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14752                          &raddr_start))
14753         ;
14754       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14755                          &raddr_stop))
14756         ;
14757       else
14758         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14759         {
14760           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14761             {
14762               clib_warning ("unsupported action: 'resolve'");
14763               return -99;
14764             }
14765         }
14766       else
14767         {
14768           clib_warning ("parse error '%U'", format_unformat_error, i);
14769           return -99;
14770         }
14771
14772     }
14773
14774   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14775
14776   mp->is_add = is_add;
14777
14778   mp->entry.spd_id = ntohl (spd_id);
14779   mp->entry.priority = ntohl (priority);
14780   mp->entry.is_outbound = is_outbound;
14781
14782   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14783                sizeof (vl_api_address_t));
14784   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14785                sizeof (vl_api_address_t));
14786   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14787                sizeof (vl_api_address_t));
14788   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14789                sizeof (vl_api_address_t));
14790
14791   mp->entry.protocol = (u8) protocol;
14792   mp->entry.local_port_start = ntohs ((u16) lport_start);
14793   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14794   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14795   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14796   mp->entry.policy = (u8) policy;
14797   mp->entry.sa_id = ntohl (sa_id);
14798
14799   S (mp);
14800   W (ret);
14801   return ret;
14802 }
14803
14804 static int
14805 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14806 {
14807   unformat_input_t *i = vam->input;
14808   vl_api_ipsec_sad_entry_add_del_t *mp;
14809   u32 sad_id = 0, spi = 0;
14810   u8 *ck = 0, *ik = 0;
14811   u8 is_add = 1;
14812
14813   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14814   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14815   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14816   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14817   vl_api_address_t tun_src, tun_dst;
14818   int ret;
14819
14820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14821     {
14822       if (unformat (i, "del"))
14823         is_add = 0;
14824       else if (unformat (i, "sad_id %d", &sad_id))
14825         ;
14826       else if (unformat (i, "spi %d", &spi))
14827         ;
14828       else if (unformat (i, "esp"))
14829         protocol = IPSEC_API_PROTO_ESP;
14830       else
14831         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14832         {
14833           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14834           if (ADDRESS_IP6 == tun_src.af)
14835             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14836         }
14837       else
14838         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14839         {
14840           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14841           if (ADDRESS_IP6 == tun_src.af)
14842             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14843         }
14844       else
14845         if (unformat (i, "crypto_alg %U",
14846                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14847         ;
14848       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14849         ;
14850       else if (unformat (i, "integ_alg %U",
14851                          unformat_ipsec_api_integ_alg, &integ_alg))
14852         ;
14853       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14854         ;
14855       else
14856         {
14857           clib_warning ("parse error '%U'", format_unformat_error, i);
14858           return -99;
14859         }
14860
14861     }
14862
14863   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14864
14865   mp->is_add = is_add;
14866   mp->entry.sad_id = ntohl (sad_id);
14867   mp->entry.protocol = protocol;
14868   mp->entry.spi = ntohl (spi);
14869   mp->entry.flags = flags;
14870
14871   mp->entry.crypto_algorithm = crypto_alg;
14872   mp->entry.integrity_algorithm = integ_alg;
14873   mp->entry.crypto_key.length = vec_len (ck);
14874   mp->entry.integrity_key.length = vec_len (ik);
14875
14876   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14877     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14878
14879   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14880     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14881
14882   if (ck)
14883     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14884   if (ik)
14885     clib_memcpy (mp->entry.integrity_key.data, ik,
14886                  mp->entry.integrity_key.length);
14887
14888   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14889     {
14890       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14891                    sizeof (mp->entry.tunnel_src));
14892       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14893                    sizeof (mp->entry.tunnel_dst));
14894     }
14895
14896   S (mp);
14897   W (ret);
14898   return ret;
14899 }
14900
14901 static int
14902 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14903 {
14904   unformat_input_t *i = vam->input;
14905   vl_api_ipsec_tunnel_if_add_del_t *mp;
14906   u32 local_spi = 0, remote_spi = 0;
14907   u32 crypto_alg = 0, integ_alg = 0;
14908   u8 *lck = NULL, *rck = NULL;
14909   u8 *lik = NULL, *rik = NULL;
14910   vl_api_address_t local_ip = { 0 };
14911   vl_api_address_t remote_ip = { 0 };
14912   f64 before = 0;
14913   u8 is_add = 1;
14914   u8 esn = 0;
14915   u8 anti_replay = 0;
14916   u8 renumber = 0;
14917   u32 instance = ~0;
14918   u32 count = 1, jj;
14919   int ret = -1;
14920
14921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (i, "del"))
14924         is_add = 0;
14925       else if (unformat (i, "esn"))
14926         esn = 1;
14927       else if (unformat (i, "anti-replay"))
14928         anti_replay = 1;
14929       else if (unformat (i, "count %d", &count))
14930         ;
14931       else if (unformat (i, "local_spi %d", &local_spi))
14932         ;
14933       else if (unformat (i, "remote_spi %d", &remote_spi))
14934         ;
14935       else
14936         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14937         ;
14938       else
14939         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14940         ;
14941       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14942         ;
14943       else
14944         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14945         ;
14946       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14947         ;
14948       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14949         ;
14950       else
14951         if (unformat
14952             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14953         {
14954           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14955             {
14956               errmsg ("unsupported crypto-alg: '%U'\n",
14957                       format_ipsec_crypto_alg, crypto_alg);
14958               return -99;
14959             }
14960         }
14961       else
14962         if (unformat
14963             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14964         {
14965           if (integ_alg >= IPSEC_INTEG_N_ALG)
14966             {
14967               errmsg ("unsupported integ-alg: '%U'\n",
14968                       format_ipsec_integ_alg, integ_alg);
14969               return -99;
14970             }
14971         }
14972       else if (unformat (i, "instance %u", &instance))
14973         renumber = 1;
14974       else
14975         {
14976           errmsg ("parse error '%U'\n", format_unformat_error, i);
14977           return -99;
14978         }
14979     }
14980
14981   if (count > 1)
14982     {
14983       /* Turn on async mode */
14984       vam->async_mode = 1;
14985       vam->async_errors = 0;
14986       before = vat_time_now (vam);
14987     }
14988
14989   for (jj = 0; jj < count; jj++)
14990     {
14991       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14992
14993       mp->is_add = is_add;
14994       mp->esn = esn;
14995       mp->anti_replay = anti_replay;
14996
14997       if (jj > 0)
14998         increment_vl_address (&remote_ip);
14999
15000       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15001       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15002
15003       mp->local_spi = htonl (local_spi + jj);
15004       mp->remote_spi = htonl (remote_spi + jj);
15005       mp->crypto_alg = (u8) crypto_alg;
15006
15007       mp->local_crypto_key_len = 0;
15008       if (lck)
15009         {
15010           mp->local_crypto_key_len = vec_len (lck);
15011           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15012             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15013           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15014         }
15015
15016       mp->remote_crypto_key_len = 0;
15017       if (rck)
15018         {
15019           mp->remote_crypto_key_len = vec_len (rck);
15020           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15021             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15022           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15023         }
15024
15025       mp->integ_alg = (u8) integ_alg;
15026
15027       mp->local_integ_key_len = 0;
15028       if (lik)
15029         {
15030           mp->local_integ_key_len = vec_len (lik);
15031           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15032             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15033           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15034         }
15035
15036       mp->remote_integ_key_len = 0;
15037       if (rik)
15038         {
15039           mp->remote_integ_key_len = vec_len (rik);
15040           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15041             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15042           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15043         }
15044
15045       if (renumber)
15046         {
15047           mp->renumber = renumber;
15048           mp->show_instance = ntohl (instance);
15049         }
15050       S (mp);
15051     }
15052
15053   /* When testing multiple add/del ops, use a control-ping to sync */
15054   if (count > 1)
15055     {
15056       vl_api_control_ping_t *mp_ping;
15057       f64 after;
15058       f64 timeout;
15059
15060       /* Shut off async mode */
15061       vam->async_mode = 0;
15062
15063       MPING (CONTROL_PING, mp_ping);
15064       S (mp_ping);
15065
15066       timeout = vat_time_now (vam) + 1.0;
15067       while (vat_time_now (vam) < timeout)
15068         if (vam->result_ready == 1)
15069           goto out;
15070       vam->retval = -99;
15071
15072     out:
15073       if (vam->retval == -99)
15074         errmsg ("timeout");
15075
15076       if (vam->async_errors > 0)
15077         {
15078           errmsg ("%d asynchronous errors", vam->async_errors);
15079           vam->retval = -98;
15080         }
15081       vam->async_errors = 0;
15082       after = vat_time_now (vam);
15083
15084       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15085       if (jj > 0)
15086         count = jj;
15087
15088       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15089              count, after - before, count / (after - before));
15090     }
15091   else
15092     {
15093       /* Wait for a reply... */
15094       W (ret);
15095       return ret;
15096     }
15097
15098   return ret;
15099 }
15100
15101 static void
15102 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15103 {
15104   vat_main_t *vam = &vat_main;
15105
15106   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15107          "crypto_key %U integ_alg %u integ_key %U flags %x "
15108          "tunnel_src_addr %U tunnel_dst_addr %U "
15109          "salt %u seq_outbound %lu last_seq_inbound %lu "
15110          "replay_window %lu\n",
15111          ntohl (mp->entry.sad_id),
15112          ntohl (mp->sw_if_index),
15113          ntohl (mp->entry.spi),
15114          ntohl (mp->entry.protocol),
15115          ntohl (mp->entry.crypto_algorithm),
15116          format_hex_bytes, mp->entry.crypto_key.data,
15117          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15118          format_hex_bytes, mp->entry.integrity_key.data,
15119          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15120          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15121          &mp->entry.tunnel_dst, ntohl (mp->salt),
15122          clib_net_to_host_u64 (mp->seq_outbound),
15123          clib_net_to_host_u64 (mp->last_seq_inbound),
15124          clib_net_to_host_u64 (mp->replay_window));
15125 }
15126
15127 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15128 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15129
15130 static void vl_api_ipsec_sa_details_t_handler_json
15131   (vl_api_ipsec_sa_details_t * mp)
15132 {
15133   vat_main_t *vam = &vat_main;
15134   vat_json_node_t *node = NULL;
15135   vl_api_ipsec_sad_flags_t flags;
15136
15137   if (VAT_JSON_ARRAY != vam->json_tree.type)
15138     {
15139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15140       vat_json_init_array (&vam->json_tree);
15141     }
15142   node = vat_json_array_add (&vam->json_tree);
15143
15144   vat_json_init_object (node);
15145   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15146   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15147   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15148   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15149   vat_json_object_add_uint (node, "crypto_alg",
15150                             ntohl (mp->entry.crypto_algorithm));
15151   vat_json_object_add_uint (node, "integ_alg",
15152                             ntohl (mp->entry.integrity_algorithm));
15153   flags = ntohl (mp->entry.flags);
15154   vat_json_object_add_uint (node, "use_esn",
15155                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15156   vat_json_object_add_uint (node, "use_anti_replay",
15157                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15158   vat_json_object_add_uint (node, "is_tunnel",
15159                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15160   vat_json_object_add_uint (node, "is_tunnel_ip6",
15161                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15162   vat_json_object_add_uint (node, "udp_encap",
15163                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15164   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15165                              mp->entry.crypto_key.length);
15166   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15167                              mp->entry.integrity_key.length);
15168   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15169   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15170   vat_json_object_add_uint (node, "replay_window",
15171                             clib_net_to_host_u64 (mp->replay_window));
15172 }
15173
15174 static int
15175 api_ipsec_sa_dump (vat_main_t * vam)
15176 {
15177   unformat_input_t *i = vam->input;
15178   vl_api_ipsec_sa_dump_t *mp;
15179   vl_api_control_ping_t *mp_ping;
15180   u32 sa_id = ~0;
15181   int ret;
15182
15183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15184     {
15185       if (unformat (i, "sa_id %d", &sa_id))
15186         ;
15187       else
15188         {
15189           clib_warning ("parse error '%U'", format_unformat_error, i);
15190           return -99;
15191         }
15192     }
15193
15194   M (IPSEC_SA_DUMP, mp);
15195
15196   mp->sa_id = ntohl (sa_id);
15197
15198   S (mp);
15199
15200   /* Use a control ping for synchronization */
15201   M (CONTROL_PING, mp_ping);
15202   S (mp_ping);
15203
15204   W (ret);
15205   return ret;
15206 }
15207
15208 static int
15209 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15210 {
15211   unformat_input_t *i = vam->input;
15212   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15213   u32 sw_if_index = ~0;
15214   u32 sa_id = ~0;
15215   u8 is_outbound = (u8) ~ 0;
15216   int ret;
15217
15218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15219     {
15220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15221         ;
15222       else if (unformat (i, "sa_id %d", &sa_id))
15223         ;
15224       else if (unformat (i, "outbound"))
15225         is_outbound = 1;
15226       else if (unformat (i, "inbound"))
15227         is_outbound = 0;
15228       else
15229         {
15230           clib_warning ("parse error '%U'", format_unformat_error, i);
15231           return -99;
15232         }
15233     }
15234
15235   if (sw_if_index == ~0)
15236     {
15237       errmsg ("interface must be specified");
15238       return -99;
15239     }
15240
15241   if (sa_id == ~0)
15242     {
15243       errmsg ("SA ID must be specified");
15244       return -99;
15245     }
15246
15247   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15248
15249   mp->sw_if_index = htonl (sw_if_index);
15250   mp->sa_id = htonl (sa_id);
15251   mp->is_outbound = is_outbound;
15252
15253   S (mp);
15254   W (ret);
15255
15256   return ret;
15257 }
15258
15259 static int
15260 api_get_first_msg_id (vat_main_t * vam)
15261 {
15262   vl_api_get_first_msg_id_t *mp;
15263   unformat_input_t *i = vam->input;
15264   u8 *name;
15265   u8 name_set = 0;
15266   int ret;
15267
15268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15269     {
15270       if (unformat (i, "client %s", &name))
15271         name_set = 1;
15272       else
15273         break;
15274     }
15275
15276   if (name_set == 0)
15277     {
15278       errmsg ("missing client name");
15279       return -99;
15280     }
15281   vec_add1 (name, 0);
15282
15283   if (vec_len (name) > 63)
15284     {
15285       errmsg ("client name too long");
15286       return -99;
15287     }
15288
15289   M (GET_FIRST_MSG_ID, mp);
15290   clib_memcpy (mp->name, name, vec_len (name));
15291   S (mp);
15292   W (ret);
15293   return ret;
15294 }
15295
15296 static int
15297 api_cop_interface_enable_disable (vat_main_t * vam)
15298 {
15299   unformat_input_t *line_input = vam->input;
15300   vl_api_cop_interface_enable_disable_t *mp;
15301   u32 sw_if_index = ~0;
15302   u8 enable_disable = 1;
15303   int ret;
15304
15305   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15306     {
15307       if (unformat (line_input, "disable"))
15308         enable_disable = 0;
15309       if (unformat (line_input, "enable"))
15310         enable_disable = 1;
15311       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15312                          vam, &sw_if_index))
15313         ;
15314       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15315         ;
15316       else
15317         break;
15318     }
15319
15320   if (sw_if_index == ~0)
15321     {
15322       errmsg ("missing interface name or sw_if_index");
15323       return -99;
15324     }
15325
15326   /* Construct the API message */
15327   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15328   mp->sw_if_index = ntohl (sw_if_index);
15329   mp->enable_disable = enable_disable;
15330
15331   /* send it... */
15332   S (mp);
15333   /* Wait for the reply */
15334   W (ret);
15335   return ret;
15336 }
15337
15338 static int
15339 api_cop_whitelist_enable_disable (vat_main_t * vam)
15340 {
15341   unformat_input_t *line_input = vam->input;
15342   vl_api_cop_whitelist_enable_disable_t *mp;
15343   u32 sw_if_index = ~0;
15344   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15345   u32 fib_id = 0;
15346   int ret;
15347
15348   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15349     {
15350       if (unformat (line_input, "ip4"))
15351         ip4 = 1;
15352       else if (unformat (line_input, "ip6"))
15353         ip6 = 1;
15354       else if (unformat (line_input, "default"))
15355         default_cop = 1;
15356       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15357                          vam, &sw_if_index))
15358         ;
15359       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15360         ;
15361       else if (unformat (line_input, "fib-id %d", &fib_id))
15362         ;
15363       else
15364         break;
15365     }
15366
15367   if (sw_if_index == ~0)
15368     {
15369       errmsg ("missing interface name or sw_if_index");
15370       return -99;
15371     }
15372
15373   /* Construct the API message */
15374   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15375   mp->sw_if_index = ntohl (sw_if_index);
15376   mp->fib_id = ntohl (fib_id);
15377   mp->ip4 = ip4;
15378   mp->ip6 = ip6;
15379   mp->default_cop = default_cop;
15380
15381   /* send it... */
15382   S (mp);
15383   /* Wait for the reply */
15384   W (ret);
15385   return ret;
15386 }
15387
15388 static int
15389 api_get_node_graph (vat_main_t * vam)
15390 {
15391   vl_api_get_node_graph_t *mp;
15392   int ret;
15393
15394   M (GET_NODE_GRAPH, mp);
15395
15396   /* send it... */
15397   S (mp);
15398   /* Wait for the reply */
15399   W (ret);
15400   return ret;
15401 }
15402
15403 /* *INDENT-OFF* */
15404 /** Used for parsing LISP eids */
15405 typedef CLIB_PACKED(struct{
15406   u8 addr[16];   /**< eid address */
15407   u32 len;       /**< prefix length if IP */
15408   u8 type;      /**< type of eid */
15409 }) lisp_eid_vat_t;
15410 /* *INDENT-ON* */
15411
15412 static uword
15413 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15414 {
15415   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15416
15417   clib_memset (a, 0, sizeof (a[0]));
15418
15419   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15420     {
15421       a->type = 0;              /* ipv4 type */
15422     }
15423   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15424     {
15425       a->type = 1;              /* ipv6 type */
15426     }
15427   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15428     {
15429       a->type = 2;              /* mac type */
15430     }
15431   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15432     {
15433       a->type = 3;              /* NSH type */
15434       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15435       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15436     }
15437   else
15438     {
15439       return 0;
15440     }
15441
15442   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15443     {
15444       return 0;
15445     }
15446
15447   return 1;
15448 }
15449
15450 static int
15451 lisp_eid_size_vat (u8 type)
15452 {
15453   switch (type)
15454     {
15455     case 0:
15456       return 4;
15457     case 1:
15458       return 16;
15459     case 2:
15460       return 6;
15461     case 3:
15462       return 5;
15463     }
15464   return 0;
15465 }
15466
15467 static void
15468 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15469 {
15470   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15471 }
15472
15473 static int
15474 api_one_add_del_locator_set (vat_main_t * vam)
15475 {
15476   unformat_input_t *input = vam->input;
15477   vl_api_one_add_del_locator_set_t *mp;
15478   u8 is_add = 1;
15479   u8 *locator_set_name = NULL;
15480   u8 locator_set_name_set = 0;
15481   vl_api_local_locator_t locator, *locators = 0;
15482   u32 sw_if_index, priority, weight;
15483   u32 data_len = 0;
15484
15485   int ret;
15486   /* Parse args required to build the message */
15487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15488     {
15489       if (unformat (input, "del"))
15490         {
15491           is_add = 0;
15492         }
15493       else if (unformat (input, "locator-set %s", &locator_set_name))
15494         {
15495           locator_set_name_set = 1;
15496         }
15497       else if (unformat (input, "sw_if_index %u p %u w %u",
15498                          &sw_if_index, &priority, &weight))
15499         {
15500           locator.sw_if_index = htonl (sw_if_index);
15501           locator.priority = priority;
15502           locator.weight = weight;
15503           vec_add1 (locators, locator);
15504         }
15505       else
15506         if (unformat
15507             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15508              &sw_if_index, &priority, &weight))
15509         {
15510           locator.sw_if_index = htonl (sw_if_index);
15511           locator.priority = priority;
15512           locator.weight = weight;
15513           vec_add1 (locators, locator);
15514         }
15515       else
15516         break;
15517     }
15518
15519   if (locator_set_name_set == 0)
15520     {
15521       errmsg ("missing locator-set name");
15522       vec_free (locators);
15523       return -99;
15524     }
15525
15526   if (vec_len (locator_set_name) > 64)
15527     {
15528       errmsg ("locator-set name too long");
15529       vec_free (locator_set_name);
15530       vec_free (locators);
15531       return -99;
15532     }
15533   vec_add1 (locator_set_name, 0);
15534
15535   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15536
15537   /* Construct the API message */
15538   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15539
15540   mp->is_add = is_add;
15541   clib_memcpy (mp->locator_set_name, locator_set_name,
15542                vec_len (locator_set_name));
15543   vec_free (locator_set_name);
15544
15545   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15546   if (locators)
15547     clib_memcpy (mp->locators, locators, data_len);
15548   vec_free (locators);
15549
15550   /* send it... */
15551   S (mp);
15552
15553   /* Wait for a reply... */
15554   W (ret);
15555   return ret;
15556 }
15557
15558 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15559
15560 static int
15561 api_one_add_del_locator (vat_main_t * vam)
15562 {
15563   unformat_input_t *input = vam->input;
15564   vl_api_one_add_del_locator_t *mp;
15565   u32 tmp_if_index = ~0;
15566   u32 sw_if_index = ~0;
15567   u8 sw_if_index_set = 0;
15568   u8 sw_if_index_if_name_set = 0;
15569   u32 priority = ~0;
15570   u8 priority_set = 0;
15571   u32 weight = ~0;
15572   u8 weight_set = 0;
15573   u8 is_add = 1;
15574   u8 *locator_set_name = NULL;
15575   u8 locator_set_name_set = 0;
15576   int ret;
15577
15578   /* Parse args required to build the message */
15579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15580     {
15581       if (unformat (input, "del"))
15582         {
15583           is_add = 0;
15584         }
15585       else if (unformat (input, "locator-set %s", &locator_set_name))
15586         {
15587           locator_set_name_set = 1;
15588         }
15589       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15590                          &tmp_if_index))
15591         {
15592           sw_if_index_if_name_set = 1;
15593           sw_if_index = tmp_if_index;
15594         }
15595       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15596         {
15597           sw_if_index_set = 1;
15598           sw_if_index = tmp_if_index;
15599         }
15600       else if (unformat (input, "p %d", &priority))
15601         {
15602           priority_set = 1;
15603         }
15604       else if (unformat (input, "w %d", &weight))
15605         {
15606           weight_set = 1;
15607         }
15608       else
15609         break;
15610     }
15611
15612   if (locator_set_name_set == 0)
15613     {
15614       errmsg ("missing locator-set name");
15615       return -99;
15616     }
15617
15618   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15619     {
15620       errmsg ("missing sw_if_index");
15621       vec_free (locator_set_name);
15622       return -99;
15623     }
15624
15625   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15626     {
15627       errmsg ("cannot use both params interface name and sw_if_index");
15628       vec_free (locator_set_name);
15629       return -99;
15630     }
15631
15632   if (priority_set == 0)
15633     {
15634       errmsg ("missing locator-set priority");
15635       vec_free (locator_set_name);
15636       return -99;
15637     }
15638
15639   if (weight_set == 0)
15640     {
15641       errmsg ("missing locator-set weight");
15642       vec_free (locator_set_name);
15643       return -99;
15644     }
15645
15646   if (vec_len (locator_set_name) > 64)
15647     {
15648       errmsg ("locator-set name too long");
15649       vec_free (locator_set_name);
15650       return -99;
15651     }
15652   vec_add1 (locator_set_name, 0);
15653
15654   /* Construct the API message */
15655   M (ONE_ADD_DEL_LOCATOR, mp);
15656
15657   mp->is_add = is_add;
15658   mp->sw_if_index = ntohl (sw_if_index);
15659   mp->priority = priority;
15660   mp->weight = weight;
15661   clib_memcpy (mp->locator_set_name, locator_set_name,
15662                vec_len (locator_set_name));
15663   vec_free (locator_set_name);
15664
15665   /* send it... */
15666   S (mp);
15667
15668   /* Wait for a reply... */
15669   W (ret);
15670   return ret;
15671 }
15672
15673 #define api_lisp_add_del_locator api_one_add_del_locator
15674
15675 uword
15676 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15677 {
15678   u32 *key_id = va_arg (*args, u32 *);
15679   u8 *s = 0;
15680
15681   if (unformat (input, "%s", &s))
15682     {
15683       if (!strcmp ((char *) s, "sha1"))
15684         key_id[0] = HMAC_SHA_1_96;
15685       else if (!strcmp ((char *) s, "sha256"))
15686         key_id[0] = HMAC_SHA_256_128;
15687       else
15688         {
15689           clib_warning ("invalid key_id: '%s'", s);
15690           key_id[0] = HMAC_NO_KEY;
15691         }
15692     }
15693   else
15694     return 0;
15695
15696   vec_free (s);
15697   return 1;
15698 }
15699
15700 static int
15701 api_one_add_del_local_eid (vat_main_t * vam)
15702 {
15703   unformat_input_t *input = vam->input;
15704   vl_api_one_add_del_local_eid_t *mp;
15705   u8 is_add = 1;
15706   u8 eid_set = 0;
15707   lisp_eid_vat_t _eid, *eid = &_eid;
15708   u8 *locator_set_name = 0;
15709   u8 locator_set_name_set = 0;
15710   u32 vni = 0;
15711   u16 key_id = 0;
15712   u8 *key = 0;
15713   int ret;
15714
15715   /* Parse args required to build the message */
15716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15717     {
15718       if (unformat (input, "del"))
15719         {
15720           is_add = 0;
15721         }
15722       else if (unformat (input, "vni %d", &vni))
15723         {
15724           ;
15725         }
15726       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15727         {
15728           eid_set = 1;
15729         }
15730       else if (unformat (input, "locator-set %s", &locator_set_name))
15731         {
15732           locator_set_name_set = 1;
15733         }
15734       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15735         ;
15736       else if (unformat (input, "secret-key %_%v%_", &key))
15737         ;
15738       else
15739         break;
15740     }
15741
15742   if (locator_set_name_set == 0)
15743     {
15744       errmsg ("missing locator-set name");
15745       return -99;
15746     }
15747
15748   if (0 == eid_set)
15749     {
15750       errmsg ("EID address not set!");
15751       vec_free (locator_set_name);
15752       return -99;
15753     }
15754
15755   if (key && (0 == key_id))
15756     {
15757       errmsg ("invalid key_id!");
15758       return -99;
15759     }
15760
15761   if (vec_len (key) > 64)
15762     {
15763       errmsg ("key too long");
15764       vec_free (key);
15765       return -99;
15766     }
15767
15768   if (vec_len (locator_set_name) > 64)
15769     {
15770       errmsg ("locator-set name too long");
15771       vec_free (locator_set_name);
15772       return -99;
15773     }
15774   vec_add1 (locator_set_name, 0);
15775
15776   /* Construct the API message */
15777   M (ONE_ADD_DEL_LOCAL_EID, mp);
15778
15779   mp->is_add = is_add;
15780   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15781   mp->eid_type = eid->type;
15782   mp->prefix_len = eid->len;
15783   mp->vni = clib_host_to_net_u32 (vni);
15784   mp->key_id = clib_host_to_net_u16 (key_id);
15785   clib_memcpy (mp->locator_set_name, locator_set_name,
15786                vec_len (locator_set_name));
15787   clib_memcpy (mp->key, key, vec_len (key));
15788
15789   vec_free (locator_set_name);
15790   vec_free (key);
15791
15792   /* send it... */
15793   S (mp);
15794
15795   /* Wait for a reply... */
15796   W (ret);
15797   return ret;
15798 }
15799
15800 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15801
15802 static int
15803 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15804 {
15805   u32 dp_table = 0, vni = 0;;
15806   unformat_input_t *input = vam->input;
15807   vl_api_gpe_add_del_fwd_entry_t *mp;
15808   u8 is_add = 1;
15809   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15810   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15811   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15812   u32 action = ~0, w;
15813   ip4_address_t rmt_rloc4, lcl_rloc4;
15814   ip6_address_t rmt_rloc6, lcl_rloc6;
15815   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15816   int ret;
15817
15818   clib_memset (&rloc, 0, sizeof (rloc));
15819
15820   /* Parse args required to build the message */
15821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15822     {
15823       if (unformat (input, "del"))
15824         is_add = 0;
15825       else if (unformat (input, "add"))
15826         is_add = 1;
15827       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15828         {
15829           rmt_eid_set = 1;
15830         }
15831       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15832         {
15833           lcl_eid_set = 1;
15834         }
15835       else if (unformat (input, "vrf %d", &dp_table))
15836         ;
15837       else if (unformat (input, "bd %d", &dp_table))
15838         ;
15839       else if (unformat (input, "vni %d", &vni))
15840         ;
15841       else if (unformat (input, "w %d", &w))
15842         {
15843           if (!curr_rloc)
15844             {
15845               errmsg ("No RLOC configured for setting priority/weight!");
15846               return -99;
15847             }
15848           curr_rloc->weight = w;
15849         }
15850       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15851                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15852         {
15853           rloc.is_ip4 = 1;
15854
15855           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15856           rloc.weight = 0;
15857           vec_add1 (lcl_locs, rloc);
15858
15859           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15860           vec_add1 (rmt_locs, rloc);
15861           /* weight saved in rmt loc */
15862           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15863         }
15864       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15865                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15866         {
15867           rloc.is_ip4 = 0;
15868           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15869           rloc.weight = 0;
15870           vec_add1 (lcl_locs, rloc);
15871
15872           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15873           vec_add1 (rmt_locs, rloc);
15874           /* weight saved in rmt loc */
15875           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15876         }
15877       else if (unformat (input, "action %d", &action))
15878         {
15879           ;
15880         }
15881       else
15882         {
15883           clib_warning ("parse error '%U'", format_unformat_error, input);
15884           return -99;
15885         }
15886     }
15887
15888   if (!rmt_eid_set)
15889     {
15890       errmsg ("remote eid addresses not set");
15891       return -99;
15892     }
15893
15894   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15895     {
15896       errmsg ("eid types don't match");
15897       return -99;
15898     }
15899
15900   if (0 == rmt_locs && (u32) ~ 0 == action)
15901     {
15902       errmsg ("action not set for negative mapping");
15903       return -99;
15904     }
15905
15906   /* Construct the API message */
15907   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15908       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15909
15910   mp->is_add = is_add;
15911   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15912   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15913   mp->eid_type = rmt_eid->type;
15914   mp->dp_table = clib_host_to_net_u32 (dp_table);
15915   mp->vni = clib_host_to_net_u32 (vni);
15916   mp->rmt_len = rmt_eid->len;
15917   mp->lcl_len = lcl_eid->len;
15918   mp->action = action;
15919
15920   if (0 != rmt_locs && 0 != lcl_locs)
15921     {
15922       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15923       clib_memcpy (mp->locs, lcl_locs,
15924                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15925
15926       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15927       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15928                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15929     }
15930   vec_free (lcl_locs);
15931   vec_free (rmt_locs);
15932
15933   /* send it... */
15934   S (mp);
15935
15936   /* Wait for a reply... */
15937   W (ret);
15938   return ret;
15939 }
15940
15941 static int
15942 api_one_add_del_map_server (vat_main_t * vam)
15943 {
15944   unformat_input_t *input = vam->input;
15945   vl_api_one_add_del_map_server_t *mp;
15946   u8 is_add = 1;
15947   u8 ipv4_set = 0;
15948   u8 ipv6_set = 0;
15949   ip4_address_t ipv4;
15950   ip6_address_t ipv6;
15951   int ret;
15952
15953   /* Parse args required to build the message */
15954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15955     {
15956       if (unformat (input, "del"))
15957         {
15958           is_add = 0;
15959         }
15960       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15961         {
15962           ipv4_set = 1;
15963         }
15964       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15965         {
15966           ipv6_set = 1;
15967         }
15968       else
15969         break;
15970     }
15971
15972   if (ipv4_set && ipv6_set)
15973     {
15974       errmsg ("both eid v4 and v6 addresses set");
15975       return -99;
15976     }
15977
15978   if (!ipv4_set && !ipv6_set)
15979     {
15980       errmsg ("eid addresses not set");
15981       return -99;
15982     }
15983
15984   /* Construct the API message */
15985   M (ONE_ADD_DEL_MAP_SERVER, mp);
15986
15987   mp->is_add = is_add;
15988   if (ipv6_set)
15989     {
15990       mp->is_ipv6 = 1;
15991       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15992     }
15993   else
15994     {
15995       mp->is_ipv6 = 0;
15996       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15997     }
15998
15999   /* send it... */
16000   S (mp);
16001
16002   /* Wait for a reply... */
16003   W (ret);
16004   return ret;
16005 }
16006
16007 #define api_lisp_add_del_map_server api_one_add_del_map_server
16008
16009 static int
16010 api_one_add_del_map_resolver (vat_main_t * vam)
16011 {
16012   unformat_input_t *input = vam->input;
16013   vl_api_one_add_del_map_resolver_t *mp;
16014   u8 is_add = 1;
16015   u8 ipv4_set = 0;
16016   u8 ipv6_set = 0;
16017   ip4_address_t ipv4;
16018   ip6_address_t ipv6;
16019   int ret;
16020
16021   /* Parse args required to build the message */
16022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16023     {
16024       if (unformat (input, "del"))
16025         {
16026           is_add = 0;
16027         }
16028       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16029         {
16030           ipv4_set = 1;
16031         }
16032       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16033         {
16034           ipv6_set = 1;
16035         }
16036       else
16037         break;
16038     }
16039
16040   if (ipv4_set && ipv6_set)
16041     {
16042       errmsg ("both eid v4 and v6 addresses set");
16043       return -99;
16044     }
16045
16046   if (!ipv4_set && !ipv6_set)
16047     {
16048       errmsg ("eid addresses not set");
16049       return -99;
16050     }
16051
16052   /* Construct the API message */
16053   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16054
16055   mp->is_add = is_add;
16056   if (ipv6_set)
16057     {
16058       mp->is_ipv6 = 1;
16059       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16060     }
16061   else
16062     {
16063       mp->is_ipv6 = 0;
16064       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16065     }
16066
16067   /* send it... */
16068   S (mp);
16069
16070   /* Wait for a reply... */
16071   W (ret);
16072   return ret;
16073 }
16074
16075 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16076
16077 static int
16078 api_lisp_gpe_enable_disable (vat_main_t * vam)
16079 {
16080   unformat_input_t *input = vam->input;
16081   vl_api_gpe_enable_disable_t *mp;
16082   u8 is_set = 0;
16083   u8 is_en = 1;
16084   int ret;
16085
16086   /* Parse args required to build the message */
16087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (input, "enable"))
16090         {
16091           is_set = 1;
16092           is_en = 1;
16093         }
16094       else if (unformat (input, "disable"))
16095         {
16096           is_set = 1;
16097           is_en = 0;
16098         }
16099       else
16100         break;
16101     }
16102
16103   if (is_set == 0)
16104     {
16105       errmsg ("Value not set");
16106       return -99;
16107     }
16108
16109   /* Construct the API message */
16110   M (GPE_ENABLE_DISABLE, mp);
16111
16112   mp->is_en = is_en;
16113
16114   /* send it... */
16115   S (mp);
16116
16117   /* Wait for a reply... */
16118   W (ret);
16119   return ret;
16120 }
16121
16122 static int
16123 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16124 {
16125   unformat_input_t *input = vam->input;
16126   vl_api_one_rloc_probe_enable_disable_t *mp;
16127   u8 is_set = 0;
16128   u8 is_en = 0;
16129   int ret;
16130
16131   /* Parse args required to build the message */
16132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16133     {
16134       if (unformat (input, "enable"))
16135         {
16136           is_set = 1;
16137           is_en = 1;
16138         }
16139       else if (unformat (input, "disable"))
16140         is_set = 1;
16141       else
16142         break;
16143     }
16144
16145   if (!is_set)
16146     {
16147       errmsg ("Value not set");
16148       return -99;
16149     }
16150
16151   /* Construct the API message */
16152   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16153
16154   mp->is_enabled = is_en;
16155
16156   /* send it... */
16157   S (mp);
16158
16159   /* Wait for a reply... */
16160   W (ret);
16161   return ret;
16162 }
16163
16164 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16165
16166 static int
16167 api_one_map_register_enable_disable (vat_main_t * vam)
16168 {
16169   unformat_input_t *input = vam->input;
16170   vl_api_one_map_register_enable_disable_t *mp;
16171   u8 is_set = 0;
16172   u8 is_en = 0;
16173   int ret;
16174
16175   /* Parse args required to build the message */
16176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16177     {
16178       if (unformat (input, "enable"))
16179         {
16180           is_set = 1;
16181           is_en = 1;
16182         }
16183       else if (unformat (input, "disable"))
16184         is_set = 1;
16185       else
16186         break;
16187     }
16188
16189   if (!is_set)
16190     {
16191       errmsg ("Value not set");
16192       return -99;
16193     }
16194
16195   /* Construct the API message */
16196   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16197
16198   mp->is_enabled = is_en;
16199
16200   /* send it... */
16201   S (mp);
16202
16203   /* Wait for a reply... */
16204   W (ret);
16205   return ret;
16206 }
16207
16208 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16209
16210 static int
16211 api_one_enable_disable (vat_main_t * vam)
16212 {
16213   unformat_input_t *input = vam->input;
16214   vl_api_one_enable_disable_t *mp;
16215   u8 is_set = 0;
16216   u8 is_en = 0;
16217   int ret;
16218
16219   /* Parse args required to build the message */
16220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16221     {
16222       if (unformat (input, "enable"))
16223         {
16224           is_set = 1;
16225           is_en = 1;
16226         }
16227       else if (unformat (input, "disable"))
16228         {
16229           is_set = 1;
16230         }
16231       else
16232         break;
16233     }
16234
16235   if (!is_set)
16236     {
16237       errmsg ("Value not set");
16238       return -99;
16239     }
16240
16241   /* Construct the API message */
16242   M (ONE_ENABLE_DISABLE, mp);
16243
16244   mp->is_en = is_en;
16245
16246   /* send it... */
16247   S (mp);
16248
16249   /* Wait for a reply... */
16250   W (ret);
16251   return ret;
16252 }
16253
16254 #define api_lisp_enable_disable api_one_enable_disable
16255
16256 static int
16257 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16258 {
16259   unformat_input_t *input = vam->input;
16260   vl_api_one_enable_disable_xtr_mode_t *mp;
16261   u8 is_set = 0;
16262   u8 is_en = 0;
16263   int ret;
16264
16265   /* Parse args required to build the message */
16266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16267     {
16268       if (unformat (input, "enable"))
16269         {
16270           is_set = 1;
16271           is_en = 1;
16272         }
16273       else if (unformat (input, "disable"))
16274         {
16275           is_set = 1;
16276         }
16277       else
16278         break;
16279     }
16280
16281   if (!is_set)
16282     {
16283       errmsg ("Value not set");
16284       return -99;
16285     }
16286
16287   /* Construct the API message */
16288   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16289
16290   mp->is_en = is_en;
16291
16292   /* send it... */
16293   S (mp);
16294
16295   /* Wait for a reply... */
16296   W (ret);
16297   return ret;
16298 }
16299
16300 static int
16301 api_one_show_xtr_mode (vat_main_t * vam)
16302 {
16303   vl_api_one_show_xtr_mode_t *mp;
16304   int ret;
16305
16306   /* Construct the API message */
16307   M (ONE_SHOW_XTR_MODE, mp);
16308
16309   /* send it... */
16310   S (mp);
16311
16312   /* Wait for a reply... */
16313   W (ret);
16314   return ret;
16315 }
16316
16317 static int
16318 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16319 {
16320   unformat_input_t *input = vam->input;
16321   vl_api_one_enable_disable_pitr_mode_t *mp;
16322   u8 is_set = 0;
16323   u8 is_en = 0;
16324   int ret;
16325
16326   /* Parse args required to build the message */
16327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16328     {
16329       if (unformat (input, "enable"))
16330         {
16331           is_set = 1;
16332           is_en = 1;
16333         }
16334       else if (unformat (input, "disable"))
16335         {
16336           is_set = 1;
16337         }
16338       else
16339         break;
16340     }
16341
16342   if (!is_set)
16343     {
16344       errmsg ("Value not set");
16345       return -99;
16346     }
16347
16348   /* Construct the API message */
16349   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16350
16351   mp->is_en = is_en;
16352
16353   /* send it... */
16354   S (mp);
16355
16356   /* Wait for a reply... */
16357   W (ret);
16358   return ret;
16359 }
16360
16361 static int
16362 api_one_show_pitr_mode (vat_main_t * vam)
16363 {
16364   vl_api_one_show_pitr_mode_t *mp;
16365   int ret;
16366
16367   /* Construct the API message */
16368   M (ONE_SHOW_PITR_MODE, mp);
16369
16370   /* send it... */
16371   S (mp);
16372
16373   /* Wait for a reply... */
16374   W (ret);
16375   return ret;
16376 }
16377
16378 static int
16379 api_one_enable_disable_petr_mode (vat_main_t * vam)
16380 {
16381   unformat_input_t *input = vam->input;
16382   vl_api_one_enable_disable_petr_mode_t *mp;
16383   u8 is_set = 0;
16384   u8 is_en = 0;
16385   int ret;
16386
16387   /* Parse args required to build the message */
16388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16389     {
16390       if (unformat (input, "enable"))
16391         {
16392           is_set = 1;
16393           is_en = 1;
16394         }
16395       else if (unformat (input, "disable"))
16396         {
16397           is_set = 1;
16398         }
16399       else
16400         break;
16401     }
16402
16403   if (!is_set)
16404     {
16405       errmsg ("Value not set");
16406       return -99;
16407     }
16408
16409   /* Construct the API message */
16410   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16411
16412   mp->is_en = is_en;
16413
16414   /* send it... */
16415   S (mp);
16416
16417   /* Wait for a reply... */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 static int
16423 api_one_show_petr_mode (vat_main_t * vam)
16424 {
16425   vl_api_one_show_petr_mode_t *mp;
16426   int ret;
16427
16428   /* Construct the API message */
16429   M (ONE_SHOW_PETR_MODE, mp);
16430
16431   /* send it... */
16432   S (mp);
16433
16434   /* Wait for a reply... */
16435   W (ret);
16436   return ret;
16437 }
16438
16439 static int
16440 api_show_one_map_register_state (vat_main_t * vam)
16441 {
16442   vl_api_show_one_map_register_state_t *mp;
16443   int ret;
16444
16445   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16446
16447   /* send */
16448   S (mp);
16449
16450   /* wait for reply */
16451   W (ret);
16452   return ret;
16453 }
16454
16455 #define api_show_lisp_map_register_state api_show_one_map_register_state
16456
16457 static int
16458 api_show_one_rloc_probe_state (vat_main_t * vam)
16459 {
16460   vl_api_show_one_rloc_probe_state_t *mp;
16461   int ret;
16462
16463   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16464
16465   /* send */
16466   S (mp);
16467
16468   /* wait for reply */
16469   W (ret);
16470   return ret;
16471 }
16472
16473 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16474
16475 static int
16476 api_one_add_del_ndp_entry (vat_main_t * vam)
16477 {
16478   vl_api_one_add_del_ndp_entry_t *mp;
16479   unformat_input_t *input = vam->input;
16480   u8 is_add = 1;
16481   u8 mac_set = 0;
16482   u8 bd_set = 0;
16483   u8 ip_set = 0;
16484   u8 mac[6] = { 0, };
16485   u8 ip6[16] = { 0, };
16486   u32 bd = ~0;
16487   int ret;
16488
16489   /* Parse args required to build the message */
16490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16491     {
16492       if (unformat (input, "del"))
16493         is_add = 0;
16494       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16495         mac_set = 1;
16496       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16497         ip_set = 1;
16498       else if (unformat (input, "bd %d", &bd))
16499         bd_set = 1;
16500       else
16501         {
16502           errmsg ("parse error '%U'", format_unformat_error, input);
16503           return -99;
16504         }
16505     }
16506
16507   if (!bd_set || !ip_set || (!mac_set && is_add))
16508     {
16509       errmsg ("Missing BD, IP or MAC!");
16510       return -99;
16511     }
16512
16513   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16514   mp->is_add = is_add;
16515   clib_memcpy (mp->mac, mac, 6);
16516   mp->bd = clib_host_to_net_u32 (bd);
16517   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16518
16519   /* send */
16520   S (mp);
16521
16522   /* wait for reply */
16523   W (ret);
16524   return ret;
16525 }
16526
16527 static int
16528 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16529 {
16530   vl_api_one_add_del_l2_arp_entry_t *mp;
16531   unformat_input_t *input = vam->input;
16532   u8 is_add = 1;
16533   u8 mac_set = 0;
16534   u8 bd_set = 0;
16535   u8 ip_set = 0;
16536   u8 mac[6] = { 0, };
16537   u32 ip4 = 0, bd = ~0;
16538   int ret;
16539
16540   /* Parse args required to build the message */
16541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16542     {
16543       if (unformat (input, "del"))
16544         is_add = 0;
16545       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16546         mac_set = 1;
16547       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16548         ip_set = 1;
16549       else if (unformat (input, "bd %d", &bd))
16550         bd_set = 1;
16551       else
16552         {
16553           errmsg ("parse error '%U'", format_unformat_error, input);
16554           return -99;
16555         }
16556     }
16557
16558   if (!bd_set || !ip_set || (!mac_set && is_add))
16559     {
16560       errmsg ("Missing BD, IP or MAC!");
16561       return -99;
16562     }
16563
16564   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16565   mp->is_add = is_add;
16566   clib_memcpy (mp->mac, mac, 6);
16567   mp->bd = clib_host_to_net_u32 (bd);
16568   mp->ip4 = ip4;
16569
16570   /* send */
16571   S (mp);
16572
16573   /* wait for reply */
16574   W (ret);
16575   return ret;
16576 }
16577
16578 static int
16579 api_one_ndp_bd_get (vat_main_t * vam)
16580 {
16581   vl_api_one_ndp_bd_get_t *mp;
16582   int ret;
16583
16584   M (ONE_NDP_BD_GET, mp);
16585
16586   /* send */
16587   S (mp);
16588
16589   /* wait for reply */
16590   W (ret);
16591   return ret;
16592 }
16593
16594 static int
16595 api_one_ndp_entries_get (vat_main_t * vam)
16596 {
16597   vl_api_one_ndp_entries_get_t *mp;
16598   unformat_input_t *input = vam->input;
16599   u8 bd_set = 0;
16600   u32 bd = ~0;
16601   int ret;
16602
16603   /* Parse args required to build the message */
16604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16605     {
16606       if (unformat (input, "bd %d", &bd))
16607         bd_set = 1;
16608       else
16609         {
16610           errmsg ("parse error '%U'", format_unformat_error, input);
16611           return -99;
16612         }
16613     }
16614
16615   if (!bd_set)
16616     {
16617       errmsg ("Expected bridge domain!");
16618       return -99;
16619     }
16620
16621   M (ONE_NDP_ENTRIES_GET, mp);
16622   mp->bd = clib_host_to_net_u32 (bd);
16623
16624   /* send */
16625   S (mp);
16626
16627   /* wait for reply */
16628   W (ret);
16629   return ret;
16630 }
16631
16632 static int
16633 api_one_l2_arp_bd_get (vat_main_t * vam)
16634 {
16635   vl_api_one_l2_arp_bd_get_t *mp;
16636   int ret;
16637
16638   M (ONE_L2_ARP_BD_GET, mp);
16639
16640   /* send */
16641   S (mp);
16642
16643   /* wait for reply */
16644   W (ret);
16645   return ret;
16646 }
16647
16648 static int
16649 api_one_l2_arp_entries_get (vat_main_t * vam)
16650 {
16651   vl_api_one_l2_arp_entries_get_t *mp;
16652   unformat_input_t *input = vam->input;
16653   u8 bd_set = 0;
16654   u32 bd = ~0;
16655   int ret;
16656
16657   /* Parse args required to build the message */
16658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16659     {
16660       if (unformat (input, "bd %d", &bd))
16661         bd_set = 1;
16662       else
16663         {
16664           errmsg ("parse error '%U'", format_unformat_error, input);
16665           return -99;
16666         }
16667     }
16668
16669   if (!bd_set)
16670     {
16671       errmsg ("Expected bridge domain!");
16672       return -99;
16673     }
16674
16675   M (ONE_L2_ARP_ENTRIES_GET, mp);
16676   mp->bd = clib_host_to_net_u32 (bd);
16677
16678   /* send */
16679   S (mp);
16680
16681   /* wait for reply */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 static int
16687 api_one_stats_enable_disable (vat_main_t * vam)
16688 {
16689   vl_api_one_stats_enable_disable_t *mp;
16690   unformat_input_t *input = vam->input;
16691   u8 is_set = 0;
16692   u8 is_en = 0;
16693   int ret;
16694
16695   /* Parse args required to build the message */
16696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16697     {
16698       if (unformat (input, "enable"))
16699         {
16700           is_set = 1;
16701           is_en = 1;
16702         }
16703       else if (unformat (input, "disable"))
16704         {
16705           is_set = 1;
16706         }
16707       else
16708         break;
16709     }
16710
16711   if (!is_set)
16712     {
16713       errmsg ("Value not set");
16714       return -99;
16715     }
16716
16717   M (ONE_STATS_ENABLE_DISABLE, mp);
16718   mp->is_en = is_en;
16719
16720   /* send */
16721   S (mp);
16722
16723   /* wait for reply */
16724   W (ret);
16725   return ret;
16726 }
16727
16728 static int
16729 api_show_one_stats_enable_disable (vat_main_t * vam)
16730 {
16731   vl_api_show_one_stats_enable_disable_t *mp;
16732   int ret;
16733
16734   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16735
16736   /* send */
16737   S (mp);
16738
16739   /* wait for reply */
16740   W (ret);
16741   return ret;
16742 }
16743
16744 static int
16745 api_show_one_map_request_mode (vat_main_t * vam)
16746 {
16747   vl_api_show_one_map_request_mode_t *mp;
16748   int ret;
16749
16750   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16751
16752   /* send */
16753   S (mp);
16754
16755   /* wait for reply */
16756   W (ret);
16757   return ret;
16758 }
16759
16760 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16761
16762 static int
16763 api_one_map_request_mode (vat_main_t * vam)
16764 {
16765   unformat_input_t *input = vam->input;
16766   vl_api_one_map_request_mode_t *mp;
16767   u8 mode = 0;
16768   int ret;
16769
16770   /* Parse args required to build the message */
16771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16772     {
16773       if (unformat (input, "dst-only"))
16774         mode = 0;
16775       else if (unformat (input, "src-dst"))
16776         mode = 1;
16777       else
16778         {
16779           errmsg ("parse error '%U'", format_unformat_error, input);
16780           return -99;
16781         }
16782     }
16783
16784   M (ONE_MAP_REQUEST_MODE, mp);
16785
16786   mp->mode = mode;
16787
16788   /* send */
16789   S (mp);
16790
16791   /* wait for reply */
16792   W (ret);
16793   return ret;
16794 }
16795
16796 #define api_lisp_map_request_mode api_one_map_request_mode
16797
16798 /**
16799  * Enable/disable ONE proxy ITR.
16800  *
16801  * @param vam vpp API test context
16802  * @return return code
16803  */
16804 static int
16805 api_one_pitr_set_locator_set (vat_main_t * vam)
16806 {
16807   u8 ls_name_set = 0;
16808   unformat_input_t *input = vam->input;
16809   vl_api_one_pitr_set_locator_set_t *mp;
16810   u8 is_add = 1;
16811   u8 *ls_name = 0;
16812   int ret;
16813
16814   /* Parse args required to build the message */
16815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (input, "del"))
16818         is_add = 0;
16819       else if (unformat (input, "locator-set %s", &ls_name))
16820         ls_name_set = 1;
16821       else
16822         {
16823           errmsg ("parse error '%U'", format_unformat_error, input);
16824           return -99;
16825         }
16826     }
16827
16828   if (!ls_name_set)
16829     {
16830       errmsg ("locator-set name not set!");
16831       return -99;
16832     }
16833
16834   M (ONE_PITR_SET_LOCATOR_SET, mp);
16835
16836   mp->is_add = is_add;
16837   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16838   vec_free (ls_name);
16839
16840   /* send */
16841   S (mp);
16842
16843   /* wait for reply */
16844   W (ret);
16845   return ret;
16846 }
16847
16848 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16849
16850 static int
16851 api_one_nsh_set_locator_set (vat_main_t * vam)
16852 {
16853   u8 ls_name_set = 0;
16854   unformat_input_t *input = vam->input;
16855   vl_api_one_nsh_set_locator_set_t *mp;
16856   u8 is_add = 1;
16857   u8 *ls_name = 0;
16858   int ret;
16859
16860   /* Parse args required to build the message */
16861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16862     {
16863       if (unformat (input, "del"))
16864         is_add = 0;
16865       else if (unformat (input, "ls %s", &ls_name))
16866         ls_name_set = 1;
16867       else
16868         {
16869           errmsg ("parse error '%U'", format_unformat_error, input);
16870           return -99;
16871         }
16872     }
16873
16874   if (!ls_name_set && is_add)
16875     {
16876       errmsg ("locator-set name not set!");
16877       return -99;
16878     }
16879
16880   M (ONE_NSH_SET_LOCATOR_SET, mp);
16881
16882   mp->is_add = is_add;
16883   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16884   vec_free (ls_name);
16885
16886   /* send */
16887   S (mp);
16888
16889   /* wait for reply */
16890   W (ret);
16891   return ret;
16892 }
16893
16894 static int
16895 api_show_one_pitr (vat_main_t * vam)
16896 {
16897   vl_api_show_one_pitr_t *mp;
16898   int ret;
16899
16900   if (!vam->json_output)
16901     {
16902       print (vam->ofp, "%=20s", "lisp status:");
16903     }
16904
16905   M (SHOW_ONE_PITR, mp);
16906   /* send it... */
16907   S (mp);
16908
16909   /* Wait for a reply... */
16910   W (ret);
16911   return ret;
16912 }
16913
16914 #define api_show_lisp_pitr api_show_one_pitr
16915
16916 static int
16917 api_one_use_petr (vat_main_t * vam)
16918 {
16919   unformat_input_t *input = vam->input;
16920   vl_api_one_use_petr_t *mp;
16921   u8 is_add = 0;
16922   ip_address_t ip;
16923   int ret;
16924
16925   clib_memset (&ip, 0, sizeof (ip));
16926
16927   /* Parse args required to build the message */
16928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16929     {
16930       if (unformat (input, "disable"))
16931         is_add = 0;
16932       else
16933         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16934         {
16935           is_add = 1;
16936           ip_addr_version (&ip) = IP4;
16937         }
16938       else
16939         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16940         {
16941           is_add = 1;
16942           ip_addr_version (&ip) = IP6;
16943         }
16944       else
16945         {
16946           errmsg ("parse error '%U'", format_unformat_error, input);
16947           return -99;
16948         }
16949     }
16950
16951   M (ONE_USE_PETR, mp);
16952
16953   mp->is_add = is_add;
16954   if (is_add)
16955     {
16956       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16957       if (mp->is_ip4)
16958         clib_memcpy (mp->address, &ip, 4);
16959       else
16960         clib_memcpy (mp->address, &ip, 16);
16961     }
16962
16963   /* send */
16964   S (mp);
16965
16966   /* wait for reply */
16967   W (ret);
16968   return ret;
16969 }
16970
16971 #define api_lisp_use_petr api_one_use_petr
16972
16973 static int
16974 api_show_one_nsh_mapping (vat_main_t * vam)
16975 {
16976   vl_api_show_one_use_petr_t *mp;
16977   int ret;
16978
16979   if (!vam->json_output)
16980     {
16981       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16982     }
16983
16984   M (SHOW_ONE_NSH_MAPPING, mp);
16985   /* send it... */
16986   S (mp);
16987
16988   /* Wait for a reply... */
16989   W (ret);
16990   return ret;
16991 }
16992
16993 static int
16994 api_show_one_use_petr (vat_main_t * vam)
16995 {
16996   vl_api_show_one_use_petr_t *mp;
16997   int ret;
16998
16999   if (!vam->json_output)
17000     {
17001       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17002     }
17003
17004   M (SHOW_ONE_USE_PETR, mp);
17005   /* send it... */
17006   S (mp);
17007
17008   /* Wait for a reply... */
17009   W (ret);
17010   return ret;
17011 }
17012
17013 #define api_show_lisp_use_petr api_show_one_use_petr
17014
17015 /**
17016  * Add/delete mapping between vni and vrf
17017  */
17018 static int
17019 api_one_eid_table_add_del_map (vat_main_t * vam)
17020 {
17021   unformat_input_t *input = vam->input;
17022   vl_api_one_eid_table_add_del_map_t *mp;
17023   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17024   u32 vni, vrf, bd_index;
17025   int ret;
17026
17027   /* Parse args required to build the message */
17028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17029     {
17030       if (unformat (input, "del"))
17031         is_add = 0;
17032       else if (unformat (input, "vrf %d", &vrf))
17033         vrf_set = 1;
17034       else if (unformat (input, "bd_index %d", &bd_index))
17035         bd_index_set = 1;
17036       else if (unformat (input, "vni %d", &vni))
17037         vni_set = 1;
17038       else
17039         break;
17040     }
17041
17042   if (!vni_set || (!vrf_set && !bd_index_set))
17043     {
17044       errmsg ("missing arguments!");
17045       return -99;
17046     }
17047
17048   if (vrf_set && bd_index_set)
17049     {
17050       errmsg ("error: both vrf and bd entered!");
17051       return -99;
17052     }
17053
17054   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17055
17056   mp->is_add = is_add;
17057   mp->vni = htonl (vni);
17058   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17059   mp->is_l2 = bd_index_set;
17060
17061   /* send */
17062   S (mp);
17063
17064   /* wait for reply */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17070
17071 uword
17072 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17073 {
17074   u32 *action = va_arg (*args, u32 *);
17075   u8 *s = 0;
17076
17077   if (unformat (input, "%s", &s))
17078     {
17079       if (!strcmp ((char *) s, "no-action"))
17080         action[0] = 0;
17081       else if (!strcmp ((char *) s, "natively-forward"))
17082         action[0] = 1;
17083       else if (!strcmp ((char *) s, "send-map-request"))
17084         action[0] = 2;
17085       else if (!strcmp ((char *) s, "drop"))
17086         action[0] = 3;
17087       else
17088         {
17089           clib_warning ("invalid action: '%s'", s);
17090           action[0] = 3;
17091         }
17092     }
17093   else
17094     return 0;
17095
17096   vec_free (s);
17097   return 1;
17098 }
17099
17100 /**
17101  * Add/del remote mapping to/from ONE control plane
17102  *
17103  * @param vam vpp API test context
17104  * @return return code
17105  */
17106 static int
17107 api_one_add_del_remote_mapping (vat_main_t * vam)
17108 {
17109   unformat_input_t *input = vam->input;
17110   vl_api_one_add_del_remote_mapping_t *mp;
17111   u32 vni = 0;
17112   lisp_eid_vat_t _eid, *eid = &_eid;
17113   lisp_eid_vat_t _seid, *seid = &_seid;
17114   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17115   u32 action = ~0, p, w, data_len;
17116   ip4_address_t rloc4;
17117   ip6_address_t rloc6;
17118   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17119   int ret;
17120
17121   clib_memset (&rloc, 0, sizeof (rloc));
17122
17123   /* Parse args required to build the message */
17124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (input, "del-all"))
17127         {
17128           del_all = 1;
17129         }
17130       else if (unformat (input, "del"))
17131         {
17132           is_add = 0;
17133         }
17134       else if (unformat (input, "add"))
17135         {
17136           is_add = 1;
17137         }
17138       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17139         {
17140           eid_set = 1;
17141         }
17142       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17143         {
17144           seid_set = 1;
17145         }
17146       else if (unformat (input, "vni %d", &vni))
17147         {
17148           ;
17149         }
17150       else if (unformat (input, "p %d w %d", &p, &w))
17151         {
17152           if (!curr_rloc)
17153             {
17154               errmsg ("No RLOC configured for setting priority/weight!");
17155               return -99;
17156             }
17157           curr_rloc->priority = p;
17158           curr_rloc->weight = w;
17159         }
17160       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17161         {
17162           rloc.is_ip4 = 1;
17163           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17164           vec_add1 (rlocs, rloc);
17165           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17166         }
17167       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17168         {
17169           rloc.is_ip4 = 0;
17170           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17171           vec_add1 (rlocs, rloc);
17172           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17173         }
17174       else if (unformat (input, "action %U",
17175                          unformat_negative_mapping_action, &action))
17176         {
17177           ;
17178         }
17179       else
17180         {
17181           clib_warning ("parse error '%U'", format_unformat_error, input);
17182           return -99;
17183         }
17184     }
17185
17186   if (0 == eid_set)
17187     {
17188       errmsg ("missing params!");
17189       return -99;
17190     }
17191
17192   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17193     {
17194       errmsg ("no action set for negative map-reply!");
17195       return -99;
17196     }
17197
17198   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17199
17200   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17201   mp->is_add = is_add;
17202   mp->vni = htonl (vni);
17203   mp->action = (u8) action;
17204   mp->is_src_dst = seid_set;
17205   mp->eid_len = eid->len;
17206   mp->seid_len = seid->len;
17207   mp->del_all = del_all;
17208   mp->eid_type = eid->type;
17209   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17210   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17211
17212   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17213   clib_memcpy (mp->rlocs, rlocs, data_len);
17214   vec_free (rlocs);
17215
17216   /* send it... */
17217   S (mp);
17218
17219   /* Wait for a reply... */
17220   W (ret);
17221   return ret;
17222 }
17223
17224 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17225
17226 /**
17227  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17228  * forwarding entries in data-plane accordingly.
17229  *
17230  * @param vam vpp API test context
17231  * @return return code
17232  */
17233 static int
17234 api_one_add_del_adjacency (vat_main_t * vam)
17235 {
17236   unformat_input_t *input = vam->input;
17237   vl_api_one_add_del_adjacency_t *mp;
17238   u32 vni = 0;
17239   ip4_address_t leid4, reid4;
17240   ip6_address_t leid6, reid6;
17241   u8 reid_mac[6] = { 0 };
17242   u8 leid_mac[6] = { 0 };
17243   u8 reid_type, leid_type;
17244   u32 leid_len = 0, reid_len = 0, len;
17245   u8 is_add = 1;
17246   int ret;
17247
17248   leid_type = reid_type = (u8) ~ 0;
17249
17250   /* Parse args required to build the message */
17251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17252     {
17253       if (unformat (input, "del"))
17254         {
17255           is_add = 0;
17256         }
17257       else if (unformat (input, "add"))
17258         {
17259           is_add = 1;
17260         }
17261       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17262                          &reid4, &len))
17263         {
17264           reid_type = 0;        /* ipv4 */
17265           reid_len = len;
17266         }
17267       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17268                          &reid6, &len))
17269         {
17270           reid_type = 1;        /* ipv6 */
17271           reid_len = len;
17272         }
17273       else if (unformat (input, "reid %U", unformat_ethernet_address,
17274                          reid_mac))
17275         {
17276           reid_type = 2;        /* mac */
17277         }
17278       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17279                          &leid4, &len))
17280         {
17281           leid_type = 0;        /* ipv4 */
17282           leid_len = len;
17283         }
17284       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17285                          &leid6, &len))
17286         {
17287           leid_type = 1;        /* ipv6 */
17288           leid_len = len;
17289         }
17290       else if (unformat (input, "leid %U", unformat_ethernet_address,
17291                          leid_mac))
17292         {
17293           leid_type = 2;        /* mac */
17294         }
17295       else if (unformat (input, "vni %d", &vni))
17296         {
17297           ;
17298         }
17299       else
17300         {
17301           errmsg ("parse error '%U'", format_unformat_error, input);
17302           return -99;
17303         }
17304     }
17305
17306   if ((u8) ~ 0 == reid_type)
17307     {
17308       errmsg ("missing params!");
17309       return -99;
17310     }
17311
17312   if (leid_type != reid_type)
17313     {
17314       errmsg ("remote and local EIDs are of different types!");
17315       return -99;
17316     }
17317
17318   M (ONE_ADD_DEL_ADJACENCY, mp);
17319   mp->is_add = is_add;
17320   mp->vni = htonl (vni);
17321   mp->leid_len = leid_len;
17322   mp->reid_len = reid_len;
17323   mp->eid_type = reid_type;
17324
17325   switch (mp->eid_type)
17326     {
17327     case 0:
17328       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17329       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17330       break;
17331     case 1:
17332       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17333       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17334       break;
17335     case 2:
17336       clib_memcpy (mp->leid, leid_mac, 6);
17337       clib_memcpy (mp->reid, reid_mac, 6);
17338       break;
17339     default:
17340       errmsg ("unknown EID type %d!", mp->eid_type);
17341       return 0;
17342     }
17343
17344   /* send it... */
17345   S (mp);
17346
17347   /* Wait for a reply... */
17348   W (ret);
17349   return ret;
17350 }
17351
17352 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17353
17354 uword
17355 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17356 {
17357   u32 *mode = va_arg (*args, u32 *);
17358
17359   if (unformat (input, "lisp"))
17360     *mode = 0;
17361   else if (unformat (input, "vxlan"))
17362     *mode = 1;
17363   else
17364     return 0;
17365
17366   return 1;
17367 }
17368
17369 static int
17370 api_gpe_get_encap_mode (vat_main_t * vam)
17371 {
17372   vl_api_gpe_get_encap_mode_t *mp;
17373   int ret;
17374
17375   /* Construct the API message */
17376   M (GPE_GET_ENCAP_MODE, mp);
17377
17378   /* send it... */
17379   S (mp);
17380
17381   /* Wait for a reply... */
17382   W (ret);
17383   return ret;
17384 }
17385
17386 static int
17387 api_gpe_set_encap_mode (vat_main_t * vam)
17388 {
17389   unformat_input_t *input = vam->input;
17390   vl_api_gpe_set_encap_mode_t *mp;
17391   int ret;
17392   u32 mode = 0;
17393
17394   /* Parse args required to build the message */
17395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17396     {
17397       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17398         ;
17399       else
17400         break;
17401     }
17402
17403   /* Construct the API message */
17404   M (GPE_SET_ENCAP_MODE, mp);
17405
17406   mp->mode = mode;
17407
17408   /* send it... */
17409   S (mp);
17410
17411   /* Wait for a reply... */
17412   W (ret);
17413   return ret;
17414 }
17415
17416 static int
17417 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17418 {
17419   unformat_input_t *input = vam->input;
17420   vl_api_gpe_add_del_iface_t *mp;
17421   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17422   u32 dp_table = 0, vni = 0;
17423   int ret;
17424
17425   /* Parse args required to build the message */
17426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17427     {
17428       if (unformat (input, "up"))
17429         {
17430           action_set = 1;
17431           is_add = 1;
17432         }
17433       else if (unformat (input, "down"))
17434         {
17435           action_set = 1;
17436           is_add = 0;
17437         }
17438       else if (unformat (input, "table_id %d", &dp_table))
17439         {
17440           dp_table_set = 1;
17441         }
17442       else if (unformat (input, "bd_id %d", &dp_table))
17443         {
17444           dp_table_set = 1;
17445           is_l2 = 1;
17446         }
17447       else if (unformat (input, "vni %d", &vni))
17448         {
17449           vni_set = 1;
17450         }
17451       else
17452         break;
17453     }
17454
17455   if (action_set == 0)
17456     {
17457       errmsg ("Action not set");
17458       return -99;
17459     }
17460   if (dp_table_set == 0 || vni_set == 0)
17461     {
17462       errmsg ("vni and dp_table must be set");
17463       return -99;
17464     }
17465
17466   /* Construct the API message */
17467   M (GPE_ADD_DEL_IFACE, mp);
17468
17469   mp->is_add = is_add;
17470   mp->dp_table = clib_host_to_net_u32 (dp_table);
17471   mp->is_l2 = is_l2;
17472   mp->vni = clib_host_to_net_u32 (vni);
17473
17474   /* send it... */
17475   S (mp);
17476
17477   /* Wait for a reply... */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 static int
17483 api_one_map_register_fallback_threshold (vat_main_t * vam)
17484 {
17485   unformat_input_t *input = vam->input;
17486   vl_api_one_map_register_fallback_threshold_t *mp;
17487   u32 value = 0;
17488   u8 is_set = 0;
17489   int ret;
17490
17491   /* Parse args required to build the message */
17492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (input, "%u", &value))
17495         is_set = 1;
17496       else
17497         {
17498           clib_warning ("parse error '%U'", format_unformat_error, input);
17499           return -99;
17500         }
17501     }
17502
17503   if (!is_set)
17504     {
17505       errmsg ("fallback threshold value is missing!");
17506       return -99;
17507     }
17508
17509   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17510   mp->value = clib_host_to_net_u32 (value);
17511
17512   /* send it... */
17513   S (mp);
17514
17515   /* Wait for a reply... */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 static int
17521 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17522 {
17523   vl_api_show_one_map_register_fallback_threshold_t *mp;
17524   int ret;
17525
17526   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17527
17528   /* send it... */
17529   S (mp);
17530
17531   /* Wait for a reply... */
17532   W (ret);
17533   return ret;
17534 }
17535
17536 uword
17537 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17538 {
17539   u32 *proto = va_arg (*args, u32 *);
17540
17541   if (unformat (input, "udp"))
17542     *proto = 1;
17543   else if (unformat (input, "api"))
17544     *proto = 2;
17545   else
17546     return 0;
17547
17548   return 1;
17549 }
17550
17551 static int
17552 api_one_set_transport_protocol (vat_main_t * vam)
17553 {
17554   unformat_input_t *input = vam->input;
17555   vl_api_one_set_transport_protocol_t *mp;
17556   u8 is_set = 0;
17557   u32 protocol = 0;
17558   int ret;
17559
17560   /* Parse args required to build the message */
17561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17562     {
17563       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17564         is_set = 1;
17565       else
17566         {
17567           clib_warning ("parse error '%U'", format_unformat_error, input);
17568           return -99;
17569         }
17570     }
17571
17572   if (!is_set)
17573     {
17574       errmsg ("Transport protocol missing!");
17575       return -99;
17576     }
17577
17578   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17579   mp->protocol = (u8) protocol;
17580
17581   /* send it... */
17582   S (mp);
17583
17584   /* Wait for a reply... */
17585   W (ret);
17586   return ret;
17587 }
17588
17589 static int
17590 api_one_get_transport_protocol (vat_main_t * vam)
17591 {
17592   vl_api_one_get_transport_protocol_t *mp;
17593   int ret;
17594
17595   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17596
17597   /* send it... */
17598   S (mp);
17599
17600   /* Wait for a reply... */
17601   W (ret);
17602   return ret;
17603 }
17604
17605 static int
17606 api_one_map_register_set_ttl (vat_main_t * vam)
17607 {
17608   unformat_input_t *input = vam->input;
17609   vl_api_one_map_register_set_ttl_t *mp;
17610   u32 ttl = 0;
17611   u8 is_set = 0;
17612   int ret;
17613
17614   /* Parse args required to build the message */
17615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17616     {
17617       if (unformat (input, "%u", &ttl))
17618         is_set = 1;
17619       else
17620         {
17621           clib_warning ("parse error '%U'", format_unformat_error, input);
17622           return -99;
17623         }
17624     }
17625
17626   if (!is_set)
17627     {
17628       errmsg ("TTL value missing!");
17629       return -99;
17630     }
17631
17632   M (ONE_MAP_REGISTER_SET_TTL, mp);
17633   mp->ttl = clib_host_to_net_u32 (ttl);
17634
17635   /* send it... */
17636   S (mp);
17637
17638   /* Wait for a reply... */
17639   W (ret);
17640   return ret;
17641 }
17642
17643 static int
17644 api_show_one_map_register_ttl (vat_main_t * vam)
17645 {
17646   vl_api_show_one_map_register_ttl_t *mp;
17647   int ret;
17648
17649   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17650
17651   /* send it... */
17652   S (mp);
17653
17654   /* Wait for a reply... */
17655   W (ret);
17656   return ret;
17657 }
17658
17659 /**
17660  * Add/del map request itr rlocs from ONE control plane and updates
17661  *
17662  * @param vam vpp API test context
17663  * @return return code
17664  */
17665 static int
17666 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17667 {
17668   unformat_input_t *input = vam->input;
17669   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17670   u8 *locator_set_name = 0;
17671   u8 locator_set_name_set = 0;
17672   u8 is_add = 1;
17673   int ret;
17674
17675   /* Parse args required to build the message */
17676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17677     {
17678       if (unformat (input, "del"))
17679         {
17680           is_add = 0;
17681         }
17682       else if (unformat (input, "%_%v%_", &locator_set_name))
17683         {
17684           locator_set_name_set = 1;
17685         }
17686       else
17687         {
17688           clib_warning ("parse error '%U'", format_unformat_error, input);
17689           return -99;
17690         }
17691     }
17692
17693   if (is_add && !locator_set_name_set)
17694     {
17695       errmsg ("itr-rloc is not set!");
17696       return -99;
17697     }
17698
17699   if (is_add && vec_len (locator_set_name) > 64)
17700     {
17701       errmsg ("itr-rloc locator-set name too long");
17702       vec_free (locator_set_name);
17703       return -99;
17704     }
17705
17706   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17707   mp->is_add = is_add;
17708   if (is_add)
17709     {
17710       clib_memcpy (mp->locator_set_name, locator_set_name,
17711                    vec_len (locator_set_name));
17712     }
17713   else
17714     {
17715       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17716     }
17717   vec_free (locator_set_name);
17718
17719   /* send it... */
17720   S (mp);
17721
17722   /* Wait for a reply... */
17723   W (ret);
17724   return ret;
17725 }
17726
17727 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17728
17729 static int
17730 api_one_locator_dump (vat_main_t * vam)
17731 {
17732   unformat_input_t *input = vam->input;
17733   vl_api_one_locator_dump_t *mp;
17734   vl_api_control_ping_t *mp_ping;
17735   u8 is_index_set = 0, is_name_set = 0;
17736   u8 *ls_name = 0;
17737   u32 ls_index = ~0;
17738   int ret;
17739
17740   /* Parse args required to build the message */
17741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17742     {
17743       if (unformat (input, "ls_name %_%v%_", &ls_name))
17744         {
17745           is_name_set = 1;
17746         }
17747       else if (unformat (input, "ls_index %d", &ls_index))
17748         {
17749           is_index_set = 1;
17750         }
17751       else
17752         {
17753           errmsg ("parse error '%U'", format_unformat_error, input);
17754           return -99;
17755         }
17756     }
17757
17758   if (!is_index_set && !is_name_set)
17759     {
17760       errmsg ("error: expected one of index or name!");
17761       return -99;
17762     }
17763
17764   if (is_index_set && is_name_set)
17765     {
17766       errmsg ("error: only one param expected!");
17767       return -99;
17768     }
17769
17770   if (vec_len (ls_name) > 62)
17771     {
17772       errmsg ("error: locator set name too long!");
17773       return -99;
17774     }
17775
17776   if (!vam->json_output)
17777     {
17778       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17779     }
17780
17781   M (ONE_LOCATOR_DUMP, mp);
17782   mp->is_index_set = is_index_set;
17783
17784   if (is_index_set)
17785     mp->ls_index = clib_host_to_net_u32 (ls_index);
17786   else
17787     {
17788       vec_add1 (ls_name, 0);
17789       strncpy ((char *) mp->ls_name, (char *) ls_name,
17790                sizeof (mp->ls_name) - 1);
17791     }
17792
17793   /* send it... */
17794   S (mp);
17795
17796   /* Use a control ping for synchronization */
17797   MPING (CONTROL_PING, mp_ping);
17798   S (mp_ping);
17799
17800   /* Wait for a reply... */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_lisp_locator_dump api_one_locator_dump
17806
17807 static int
17808 api_one_locator_set_dump (vat_main_t * vam)
17809 {
17810   vl_api_one_locator_set_dump_t *mp;
17811   vl_api_control_ping_t *mp_ping;
17812   unformat_input_t *input = vam->input;
17813   u8 filter = 0;
17814   int ret;
17815
17816   /* Parse args required to build the message */
17817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (input, "local"))
17820         {
17821           filter = 1;
17822         }
17823       else if (unformat (input, "remote"))
17824         {
17825           filter = 2;
17826         }
17827       else
17828         {
17829           errmsg ("parse error '%U'", format_unformat_error, input);
17830           return -99;
17831         }
17832     }
17833
17834   if (!vam->json_output)
17835     {
17836       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17837     }
17838
17839   M (ONE_LOCATOR_SET_DUMP, mp);
17840
17841   mp->filter = filter;
17842
17843   /* send it... */
17844   S (mp);
17845
17846   /* Use a control ping for synchronization */
17847   MPING (CONTROL_PING, mp_ping);
17848   S (mp_ping);
17849
17850   /* Wait for a reply... */
17851   W (ret);
17852   return ret;
17853 }
17854
17855 #define api_lisp_locator_set_dump api_one_locator_set_dump
17856
17857 static int
17858 api_one_eid_table_map_dump (vat_main_t * vam)
17859 {
17860   u8 is_l2 = 0;
17861   u8 mode_set = 0;
17862   unformat_input_t *input = vam->input;
17863   vl_api_one_eid_table_map_dump_t *mp;
17864   vl_api_control_ping_t *mp_ping;
17865   int ret;
17866
17867   /* Parse args required to build the message */
17868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17869     {
17870       if (unformat (input, "l2"))
17871         {
17872           is_l2 = 1;
17873           mode_set = 1;
17874         }
17875       else if (unformat (input, "l3"))
17876         {
17877           is_l2 = 0;
17878           mode_set = 1;
17879         }
17880       else
17881         {
17882           errmsg ("parse error '%U'", format_unformat_error, input);
17883           return -99;
17884         }
17885     }
17886
17887   if (!mode_set)
17888     {
17889       errmsg ("expected one of 'l2' or 'l3' parameter!");
17890       return -99;
17891     }
17892
17893   if (!vam->json_output)
17894     {
17895       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17896     }
17897
17898   M (ONE_EID_TABLE_MAP_DUMP, mp);
17899   mp->is_l2 = is_l2;
17900
17901   /* send it... */
17902   S (mp);
17903
17904   /* Use a control ping for synchronization */
17905   MPING (CONTROL_PING, mp_ping);
17906   S (mp_ping);
17907
17908   /* Wait for a reply... */
17909   W (ret);
17910   return ret;
17911 }
17912
17913 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17914
17915 static int
17916 api_one_eid_table_vni_dump (vat_main_t * vam)
17917 {
17918   vl_api_one_eid_table_vni_dump_t *mp;
17919   vl_api_control_ping_t *mp_ping;
17920   int ret;
17921
17922   if (!vam->json_output)
17923     {
17924       print (vam->ofp, "VNI");
17925     }
17926
17927   M (ONE_EID_TABLE_VNI_DUMP, mp);
17928
17929   /* send it... */
17930   S (mp);
17931
17932   /* Use a control ping for synchronization */
17933   MPING (CONTROL_PING, mp_ping);
17934   S (mp_ping);
17935
17936   /* Wait for a reply... */
17937   W (ret);
17938   return ret;
17939 }
17940
17941 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17942
17943 static int
17944 api_one_eid_table_dump (vat_main_t * vam)
17945 {
17946   unformat_input_t *i = vam->input;
17947   vl_api_one_eid_table_dump_t *mp;
17948   vl_api_control_ping_t *mp_ping;
17949   struct in_addr ip4;
17950   struct in6_addr ip6;
17951   u8 mac[6];
17952   u8 eid_type = ~0, eid_set = 0;
17953   u32 prefix_length = ~0, t, vni = 0;
17954   u8 filter = 0;
17955   int ret;
17956   lisp_nsh_api_t nsh;
17957
17958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17959     {
17960       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17961         {
17962           eid_set = 1;
17963           eid_type = 0;
17964           prefix_length = t;
17965         }
17966       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17967         {
17968           eid_set = 1;
17969           eid_type = 1;
17970           prefix_length = t;
17971         }
17972       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17973         {
17974           eid_set = 1;
17975           eid_type = 2;
17976         }
17977       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17978         {
17979           eid_set = 1;
17980           eid_type = 3;
17981         }
17982       else if (unformat (i, "vni %d", &t))
17983         {
17984           vni = t;
17985         }
17986       else if (unformat (i, "local"))
17987         {
17988           filter = 1;
17989         }
17990       else if (unformat (i, "remote"))
17991         {
17992           filter = 2;
17993         }
17994       else
17995         {
17996           errmsg ("parse error '%U'", format_unformat_error, i);
17997           return -99;
17998         }
17999     }
18000
18001   if (!vam->json_output)
18002     {
18003       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18004              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18005     }
18006
18007   M (ONE_EID_TABLE_DUMP, mp);
18008
18009   mp->filter = filter;
18010   if (eid_set)
18011     {
18012       mp->eid_set = 1;
18013       mp->vni = htonl (vni);
18014       mp->eid_type = eid_type;
18015       switch (eid_type)
18016         {
18017         case 0:
18018           mp->prefix_length = prefix_length;
18019           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18020           break;
18021         case 1:
18022           mp->prefix_length = prefix_length;
18023           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18024           break;
18025         case 2:
18026           clib_memcpy (mp->eid, mac, sizeof (mac));
18027           break;
18028         case 3:
18029           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18030           break;
18031         default:
18032           errmsg ("unknown EID type %d!", eid_type);
18033           return -99;
18034         }
18035     }
18036
18037   /* send it... */
18038   S (mp);
18039
18040   /* Use a control ping for synchronization */
18041   MPING (CONTROL_PING, mp_ping);
18042   S (mp_ping);
18043
18044   /* Wait for a reply... */
18045   W (ret);
18046   return ret;
18047 }
18048
18049 #define api_lisp_eid_table_dump api_one_eid_table_dump
18050
18051 static int
18052 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18053 {
18054   unformat_input_t *i = vam->input;
18055   vl_api_gpe_fwd_entries_get_t *mp;
18056   u8 vni_set = 0;
18057   u32 vni = ~0;
18058   int ret;
18059
18060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18061     {
18062       if (unformat (i, "vni %d", &vni))
18063         {
18064           vni_set = 1;
18065         }
18066       else
18067         {
18068           errmsg ("parse error '%U'", format_unformat_error, i);
18069           return -99;
18070         }
18071     }
18072
18073   if (!vni_set)
18074     {
18075       errmsg ("vni not set!");
18076       return -99;
18077     }
18078
18079   if (!vam->json_output)
18080     {
18081       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18082              "leid", "reid");
18083     }
18084
18085   M (GPE_FWD_ENTRIES_GET, mp);
18086   mp->vni = clib_host_to_net_u32 (vni);
18087
18088   /* send it... */
18089   S (mp);
18090
18091   /* Wait for a reply... */
18092   W (ret);
18093   return ret;
18094 }
18095
18096 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18097 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18098 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18099 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18100 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18101 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18102 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18103 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18104
18105 static int
18106 api_one_adjacencies_get (vat_main_t * vam)
18107 {
18108   unformat_input_t *i = vam->input;
18109   vl_api_one_adjacencies_get_t *mp;
18110   u8 vni_set = 0;
18111   u32 vni = ~0;
18112   int ret;
18113
18114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18115     {
18116       if (unformat (i, "vni %d", &vni))
18117         {
18118           vni_set = 1;
18119         }
18120       else
18121         {
18122           errmsg ("parse error '%U'", format_unformat_error, i);
18123           return -99;
18124         }
18125     }
18126
18127   if (!vni_set)
18128     {
18129       errmsg ("vni not set!");
18130       return -99;
18131     }
18132
18133   if (!vam->json_output)
18134     {
18135       print (vam->ofp, "%s %40s", "leid", "reid");
18136     }
18137
18138   M (ONE_ADJACENCIES_GET, mp);
18139   mp->vni = clib_host_to_net_u32 (vni);
18140
18141   /* send it... */
18142   S (mp);
18143
18144   /* Wait for a reply... */
18145   W (ret);
18146   return ret;
18147 }
18148
18149 #define api_lisp_adjacencies_get api_one_adjacencies_get
18150
18151 static int
18152 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18153 {
18154   unformat_input_t *i = vam->input;
18155   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18156   int ret;
18157   u8 ip_family_set = 0, is_ip4 = 1;
18158
18159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18160     {
18161       if (unformat (i, "ip4"))
18162         {
18163           ip_family_set = 1;
18164           is_ip4 = 1;
18165         }
18166       else if (unformat (i, "ip6"))
18167         {
18168           ip_family_set = 1;
18169           is_ip4 = 0;
18170         }
18171       else
18172         {
18173           errmsg ("parse error '%U'", format_unformat_error, i);
18174           return -99;
18175         }
18176     }
18177
18178   if (!ip_family_set)
18179     {
18180       errmsg ("ip family not set!");
18181       return -99;
18182     }
18183
18184   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18185   mp->is_ip4 = is_ip4;
18186
18187   /* send it... */
18188   S (mp);
18189
18190   /* Wait for a reply... */
18191   W (ret);
18192   return ret;
18193 }
18194
18195 static int
18196 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18197 {
18198   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18199   int ret;
18200
18201   if (!vam->json_output)
18202     {
18203       print (vam->ofp, "VNIs");
18204     }
18205
18206   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18207
18208   /* send it... */
18209   S (mp);
18210
18211   /* Wait for a reply... */
18212   W (ret);
18213   return ret;
18214 }
18215
18216 static int
18217 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18218 {
18219   unformat_input_t *i = vam->input;
18220   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18221   int ret = 0;
18222   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18223   struct in_addr ip4;
18224   struct in6_addr ip6;
18225   u32 table_id = 0, nh_sw_if_index = ~0;
18226
18227   clib_memset (&ip4, 0, sizeof (ip4));
18228   clib_memset (&ip6, 0, sizeof (ip6));
18229
18230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18231     {
18232       if (unformat (i, "del"))
18233         is_add = 0;
18234       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18235                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18236         {
18237           ip_set = 1;
18238           is_ip4 = 1;
18239         }
18240       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18241                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18242         {
18243           ip_set = 1;
18244           is_ip4 = 0;
18245         }
18246       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18247         {
18248           ip_set = 1;
18249           is_ip4 = 1;
18250           nh_sw_if_index = ~0;
18251         }
18252       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18253         {
18254           ip_set = 1;
18255           is_ip4 = 0;
18256           nh_sw_if_index = ~0;
18257         }
18258       else if (unformat (i, "table %d", &table_id))
18259         ;
18260       else
18261         {
18262           errmsg ("parse error '%U'", format_unformat_error, i);
18263           return -99;
18264         }
18265     }
18266
18267   if (!ip_set)
18268     {
18269       errmsg ("nh addr not set!");
18270       return -99;
18271     }
18272
18273   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18274   mp->is_add = is_add;
18275   mp->table_id = clib_host_to_net_u32 (table_id);
18276   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18277   mp->is_ip4 = is_ip4;
18278   if (is_ip4)
18279     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18280   else
18281     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18282
18283   /* send it... */
18284   S (mp);
18285
18286   /* Wait for a reply... */
18287   W (ret);
18288   return ret;
18289 }
18290
18291 static int
18292 api_one_map_server_dump (vat_main_t * vam)
18293 {
18294   vl_api_one_map_server_dump_t *mp;
18295   vl_api_control_ping_t *mp_ping;
18296   int ret;
18297
18298   if (!vam->json_output)
18299     {
18300       print (vam->ofp, "%=20s", "Map server");
18301     }
18302
18303   M (ONE_MAP_SERVER_DUMP, mp);
18304   /* send it... */
18305   S (mp);
18306
18307   /* Use a control ping for synchronization */
18308   MPING (CONTROL_PING, mp_ping);
18309   S (mp_ping);
18310
18311   /* Wait for a reply... */
18312   W (ret);
18313   return ret;
18314 }
18315
18316 #define api_lisp_map_server_dump api_one_map_server_dump
18317
18318 static int
18319 api_one_map_resolver_dump (vat_main_t * vam)
18320 {
18321   vl_api_one_map_resolver_dump_t *mp;
18322   vl_api_control_ping_t *mp_ping;
18323   int ret;
18324
18325   if (!vam->json_output)
18326     {
18327       print (vam->ofp, "%=20s", "Map resolver");
18328     }
18329
18330   M (ONE_MAP_RESOLVER_DUMP, mp);
18331   /* send it... */
18332   S (mp);
18333
18334   /* Use a control ping for synchronization */
18335   MPING (CONTROL_PING, mp_ping);
18336   S (mp_ping);
18337
18338   /* Wait for a reply... */
18339   W (ret);
18340   return ret;
18341 }
18342
18343 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18344
18345 static int
18346 api_one_stats_flush (vat_main_t * vam)
18347 {
18348   vl_api_one_stats_flush_t *mp;
18349   int ret = 0;
18350
18351   M (ONE_STATS_FLUSH, mp);
18352   S (mp);
18353   W (ret);
18354   return ret;
18355 }
18356
18357 static int
18358 api_one_stats_dump (vat_main_t * vam)
18359 {
18360   vl_api_one_stats_dump_t *mp;
18361   vl_api_control_ping_t *mp_ping;
18362   int ret;
18363
18364   M (ONE_STATS_DUMP, mp);
18365   /* send it... */
18366   S (mp);
18367
18368   /* Use a control ping for synchronization */
18369   MPING (CONTROL_PING, mp_ping);
18370   S (mp_ping);
18371
18372   /* Wait for a reply... */
18373   W (ret);
18374   return ret;
18375 }
18376
18377 static int
18378 api_show_one_status (vat_main_t * vam)
18379 {
18380   vl_api_show_one_status_t *mp;
18381   int ret;
18382
18383   if (!vam->json_output)
18384     {
18385       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18386     }
18387
18388   M (SHOW_ONE_STATUS, mp);
18389   /* send it... */
18390   S (mp);
18391   /* Wait for a reply... */
18392   W (ret);
18393   return ret;
18394 }
18395
18396 #define api_show_lisp_status api_show_one_status
18397
18398 static int
18399 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18400 {
18401   vl_api_gpe_fwd_entry_path_dump_t *mp;
18402   vl_api_control_ping_t *mp_ping;
18403   unformat_input_t *i = vam->input;
18404   u32 fwd_entry_index = ~0;
18405   int ret;
18406
18407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18408     {
18409       if (unformat (i, "index %d", &fwd_entry_index))
18410         ;
18411       else
18412         break;
18413     }
18414
18415   if (~0 == fwd_entry_index)
18416     {
18417       errmsg ("no index specified!");
18418       return -99;
18419     }
18420
18421   if (!vam->json_output)
18422     {
18423       print (vam->ofp, "first line");
18424     }
18425
18426   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18427
18428   /* send it... */
18429   S (mp);
18430   /* Use a control ping for synchronization */
18431   MPING (CONTROL_PING, mp_ping);
18432   S (mp_ping);
18433
18434   /* Wait for a reply... */
18435   W (ret);
18436   return ret;
18437 }
18438
18439 static int
18440 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18441 {
18442   vl_api_one_get_map_request_itr_rlocs_t *mp;
18443   int ret;
18444
18445   if (!vam->json_output)
18446     {
18447       print (vam->ofp, "%=20s", "itr-rlocs:");
18448     }
18449
18450   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18451   /* send it... */
18452   S (mp);
18453   /* Wait for a reply... */
18454   W (ret);
18455   return ret;
18456 }
18457
18458 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18459
18460 static int
18461 api_af_packet_create (vat_main_t * vam)
18462 {
18463   unformat_input_t *i = vam->input;
18464   vl_api_af_packet_create_t *mp;
18465   u8 *host_if_name = 0;
18466   u8 hw_addr[6];
18467   u8 random_hw_addr = 1;
18468   int ret;
18469
18470   clib_memset (hw_addr, 0, sizeof (hw_addr));
18471
18472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18473     {
18474       if (unformat (i, "name %s", &host_if_name))
18475         vec_add1 (host_if_name, 0);
18476       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18477         random_hw_addr = 0;
18478       else
18479         break;
18480     }
18481
18482   if (!vec_len (host_if_name))
18483     {
18484       errmsg ("host-interface name must be specified");
18485       return -99;
18486     }
18487
18488   if (vec_len (host_if_name) > 64)
18489     {
18490       errmsg ("host-interface name too long");
18491       return -99;
18492     }
18493
18494   M (AF_PACKET_CREATE, mp);
18495
18496   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18497   clib_memcpy (mp->hw_addr, hw_addr, 6);
18498   mp->use_random_hw_addr = random_hw_addr;
18499   vec_free (host_if_name);
18500
18501   S (mp);
18502
18503   /* *INDENT-OFF* */
18504   W2 (ret,
18505       ({
18506         if (ret == 0)
18507           fprintf (vam->ofp ? vam->ofp : stderr,
18508                    " new sw_if_index = %d\n", vam->sw_if_index);
18509       }));
18510   /* *INDENT-ON* */
18511   return ret;
18512 }
18513
18514 static int
18515 api_af_packet_delete (vat_main_t * vam)
18516 {
18517   unformat_input_t *i = vam->input;
18518   vl_api_af_packet_delete_t *mp;
18519   u8 *host_if_name = 0;
18520   int ret;
18521
18522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18523     {
18524       if (unformat (i, "name %s", &host_if_name))
18525         vec_add1 (host_if_name, 0);
18526       else
18527         break;
18528     }
18529
18530   if (!vec_len (host_if_name))
18531     {
18532       errmsg ("host-interface name must be specified");
18533       return -99;
18534     }
18535
18536   if (vec_len (host_if_name) > 64)
18537     {
18538       errmsg ("host-interface name too long");
18539       return -99;
18540     }
18541
18542   M (AF_PACKET_DELETE, mp);
18543
18544   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18545   vec_free (host_if_name);
18546
18547   S (mp);
18548   W (ret);
18549   return ret;
18550 }
18551
18552 static void vl_api_af_packet_details_t_handler
18553   (vl_api_af_packet_details_t * mp)
18554 {
18555   vat_main_t *vam = &vat_main;
18556
18557   print (vam->ofp, "%-16s %d",
18558          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18559 }
18560
18561 static void vl_api_af_packet_details_t_handler_json
18562   (vl_api_af_packet_details_t * mp)
18563 {
18564   vat_main_t *vam = &vat_main;
18565   vat_json_node_t *node = NULL;
18566
18567   if (VAT_JSON_ARRAY != vam->json_tree.type)
18568     {
18569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18570       vat_json_init_array (&vam->json_tree);
18571     }
18572   node = vat_json_array_add (&vam->json_tree);
18573
18574   vat_json_init_object (node);
18575   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18576   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18577 }
18578
18579 static int
18580 api_af_packet_dump (vat_main_t * vam)
18581 {
18582   vl_api_af_packet_dump_t *mp;
18583   vl_api_control_ping_t *mp_ping;
18584   int ret;
18585
18586   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18587   /* Get list of tap interfaces */
18588   M (AF_PACKET_DUMP, mp);
18589   S (mp);
18590
18591   /* Use a control ping for synchronization */
18592   MPING (CONTROL_PING, mp_ping);
18593   S (mp_ping);
18594
18595   W (ret);
18596   return ret;
18597 }
18598
18599 static int
18600 api_policer_add_del (vat_main_t * vam)
18601 {
18602   unformat_input_t *i = vam->input;
18603   vl_api_policer_add_del_t *mp;
18604   u8 is_add = 1;
18605   u8 *name = 0;
18606   u32 cir = 0;
18607   u32 eir = 0;
18608   u64 cb = 0;
18609   u64 eb = 0;
18610   u8 rate_type = 0;
18611   u8 round_type = 0;
18612   u8 type = 0;
18613   u8 color_aware = 0;
18614   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18615   int ret;
18616
18617   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18618   conform_action.dscp = 0;
18619   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18620   exceed_action.dscp = 0;
18621   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18622   violate_action.dscp = 0;
18623
18624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18625     {
18626       if (unformat (i, "del"))
18627         is_add = 0;
18628       else if (unformat (i, "name %s", &name))
18629         vec_add1 (name, 0);
18630       else if (unformat (i, "cir %u", &cir))
18631         ;
18632       else if (unformat (i, "eir %u", &eir))
18633         ;
18634       else if (unformat (i, "cb %u", &cb))
18635         ;
18636       else if (unformat (i, "eb %u", &eb))
18637         ;
18638       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18639                          &rate_type))
18640         ;
18641       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18642                          &round_type))
18643         ;
18644       else if (unformat (i, "type %U", unformat_policer_type, &type))
18645         ;
18646       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18647                          &conform_action))
18648         ;
18649       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18650                          &exceed_action))
18651         ;
18652       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18653                          &violate_action))
18654         ;
18655       else if (unformat (i, "color-aware"))
18656         color_aware = 1;
18657       else
18658         break;
18659     }
18660
18661   if (!vec_len (name))
18662     {
18663       errmsg ("policer name must be specified");
18664       return -99;
18665     }
18666
18667   if (vec_len (name) > 64)
18668     {
18669       errmsg ("policer name too long");
18670       return -99;
18671     }
18672
18673   M (POLICER_ADD_DEL, mp);
18674
18675   clib_memcpy (mp->name, name, vec_len (name));
18676   vec_free (name);
18677   mp->is_add = is_add;
18678   mp->cir = ntohl (cir);
18679   mp->eir = ntohl (eir);
18680   mp->cb = clib_net_to_host_u64 (cb);
18681   mp->eb = clib_net_to_host_u64 (eb);
18682   mp->rate_type = rate_type;
18683   mp->round_type = round_type;
18684   mp->type = type;
18685   mp->conform_action_type = conform_action.action_type;
18686   mp->conform_dscp = conform_action.dscp;
18687   mp->exceed_action_type = exceed_action.action_type;
18688   mp->exceed_dscp = exceed_action.dscp;
18689   mp->violate_action_type = violate_action.action_type;
18690   mp->violate_dscp = violate_action.dscp;
18691   mp->color_aware = color_aware;
18692
18693   S (mp);
18694   W (ret);
18695   return ret;
18696 }
18697
18698 static int
18699 api_policer_dump (vat_main_t * vam)
18700 {
18701   unformat_input_t *i = vam->input;
18702   vl_api_policer_dump_t *mp;
18703   vl_api_control_ping_t *mp_ping;
18704   u8 *match_name = 0;
18705   u8 match_name_valid = 0;
18706   int ret;
18707
18708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18709     {
18710       if (unformat (i, "name %s", &match_name))
18711         {
18712           vec_add1 (match_name, 0);
18713           match_name_valid = 1;
18714         }
18715       else
18716         break;
18717     }
18718
18719   M (POLICER_DUMP, mp);
18720   mp->match_name_valid = match_name_valid;
18721   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18722   vec_free (match_name);
18723   /* send it... */
18724   S (mp);
18725
18726   /* Use a control ping for synchronization */
18727   MPING (CONTROL_PING, mp_ping);
18728   S (mp_ping);
18729
18730   /* Wait for a reply... */
18731   W (ret);
18732   return ret;
18733 }
18734
18735 static int
18736 api_policer_classify_set_interface (vat_main_t * vam)
18737 {
18738   unformat_input_t *i = vam->input;
18739   vl_api_policer_classify_set_interface_t *mp;
18740   u32 sw_if_index;
18741   int sw_if_index_set;
18742   u32 ip4_table_index = ~0;
18743   u32 ip6_table_index = ~0;
18744   u32 l2_table_index = ~0;
18745   u8 is_add = 1;
18746   int ret;
18747
18748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18749     {
18750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18751         sw_if_index_set = 1;
18752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18753         sw_if_index_set = 1;
18754       else if (unformat (i, "del"))
18755         is_add = 0;
18756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18757         ;
18758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18759         ;
18760       else if (unformat (i, "l2-table %d", &l2_table_index))
18761         ;
18762       else
18763         {
18764           clib_warning ("parse error '%U'", format_unformat_error, i);
18765           return -99;
18766         }
18767     }
18768
18769   if (sw_if_index_set == 0)
18770     {
18771       errmsg ("missing interface name or sw_if_index");
18772       return -99;
18773     }
18774
18775   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18776
18777   mp->sw_if_index = ntohl (sw_if_index);
18778   mp->ip4_table_index = ntohl (ip4_table_index);
18779   mp->ip6_table_index = ntohl (ip6_table_index);
18780   mp->l2_table_index = ntohl (l2_table_index);
18781   mp->is_add = is_add;
18782
18783   S (mp);
18784   W (ret);
18785   return ret;
18786 }
18787
18788 static int
18789 api_policer_classify_dump (vat_main_t * vam)
18790 {
18791   unformat_input_t *i = vam->input;
18792   vl_api_policer_classify_dump_t *mp;
18793   vl_api_control_ping_t *mp_ping;
18794   u8 type = POLICER_CLASSIFY_N_TABLES;
18795   int ret;
18796
18797   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18798     ;
18799   else
18800     {
18801       errmsg ("classify table type must be specified");
18802       return -99;
18803     }
18804
18805   if (!vam->json_output)
18806     {
18807       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18808     }
18809
18810   M (POLICER_CLASSIFY_DUMP, mp);
18811   mp->type = type;
18812   /* send it... */
18813   S (mp);
18814
18815   /* Use a control ping for synchronization */
18816   MPING (CONTROL_PING, mp_ping);
18817   S (mp_ping);
18818
18819   /* Wait for a reply... */
18820   W (ret);
18821   return ret;
18822 }
18823
18824 static int
18825 api_netmap_create (vat_main_t * vam)
18826 {
18827   unformat_input_t *i = vam->input;
18828   vl_api_netmap_create_t *mp;
18829   u8 *if_name = 0;
18830   u8 hw_addr[6];
18831   u8 random_hw_addr = 1;
18832   u8 is_pipe = 0;
18833   u8 is_master = 0;
18834   int ret;
18835
18836   clib_memset (hw_addr, 0, sizeof (hw_addr));
18837
18838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18839     {
18840       if (unformat (i, "name %s", &if_name))
18841         vec_add1 (if_name, 0);
18842       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18843         random_hw_addr = 0;
18844       else if (unformat (i, "pipe"))
18845         is_pipe = 1;
18846       else if (unformat (i, "master"))
18847         is_master = 1;
18848       else if (unformat (i, "slave"))
18849         is_master = 0;
18850       else
18851         break;
18852     }
18853
18854   if (!vec_len (if_name))
18855     {
18856       errmsg ("interface name must be specified");
18857       return -99;
18858     }
18859
18860   if (vec_len (if_name) > 64)
18861     {
18862       errmsg ("interface name too long");
18863       return -99;
18864     }
18865
18866   M (NETMAP_CREATE, mp);
18867
18868   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18869   clib_memcpy (mp->hw_addr, hw_addr, 6);
18870   mp->use_random_hw_addr = random_hw_addr;
18871   mp->is_pipe = is_pipe;
18872   mp->is_master = is_master;
18873   vec_free (if_name);
18874
18875   S (mp);
18876   W (ret);
18877   return ret;
18878 }
18879
18880 static int
18881 api_netmap_delete (vat_main_t * vam)
18882 {
18883   unformat_input_t *i = vam->input;
18884   vl_api_netmap_delete_t *mp;
18885   u8 *if_name = 0;
18886   int ret;
18887
18888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18889     {
18890       if (unformat (i, "name %s", &if_name))
18891         vec_add1 (if_name, 0);
18892       else
18893         break;
18894     }
18895
18896   if (!vec_len (if_name))
18897     {
18898       errmsg ("interface name must be specified");
18899       return -99;
18900     }
18901
18902   if (vec_len (if_name) > 64)
18903     {
18904       errmsg ("interface name too long");
18905       return -99;
18906     }
18907
18908   M (NETMAP_DELETE, mp);
18909
18910   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18911   vec_free (if_name);
18912
18913   S (mp);
18914   W (ret);
18915   return ret;
18916 }
18917
18918 static void
18919 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18920 {
18921   if (fp->afi == IP46_TYPE_IP6)
18922     print (vam->ofp,
18923            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18924            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18925            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18926            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18927            format_ip6_address, fp->next_hop);
18928   else if (fp->afi == IP46_TYPE_IP4)
18929     print (vam->ofp,
18930            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18931            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18932            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18933            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18934            format_ip4_address, fp->next_hop);
18935 }
18936
18937 static void
18938 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18939                                  vl_api_fib_path_t * fp)
18940 {
18941   struct in_addr ip4;
18942   struct in6_addr ip6;
18943
18944   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18945   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18946   vat_json_object_add_uint (node, "is_local", fp->is_local);
18947   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18948   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18949   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18950   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18951   if (fp->afi == IP46_TYPE_IP4)
18952     {
18953       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18954       vat_json_object_add_ip4 (node, "next_hop", ip4);
18955     }
18956   else if (fp->afi == IP46_TYPE_IP6)
18957     {
18958       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18959       vat_json_object_add_ip6 (node, "next_hop", ip6);
18960     }
18961 }
18962
18963 static void
18964 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18965 {
18966   vat_main_t *vam = &vat_main;
18967   int count = ntohl (mp->mt_count);
18968   vl_api_fib_path_t *fp;
18969   i32 i;
18970
18971   print (vam->ofp, "[%d]: sw_if_index %d via:",
18972          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18973   fp = mp->mt_paths;
18974   for (i = 0; i < count; i++)
18975     {
18976       vl_api_mpls_fib_path_print (vam, fp);
18977       fp++;
18978     }
18979
18980   print (vam->ofp, "");
18981 }
18982
18983 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18984 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18985
18986 static void
18987 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18988 {
18989   vat_main_t *vam = &vat_main;
18990   vat_json_node_t *node = NULL;
18991   int count = ntohl (mp->mt_count);
18992   vl_api_fib_path_t *fp;
18993   i32 i;
18994
18995   if (VAT_JSON_ARRAY != vam->json_tree.type)
18996     {
18997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18998       vat_json_init_array (&vam->json_tree);
18999     }
19000   node = vat_json_array_add (&vam->json_tree);
19001
19002   vat_json_init_object (node);
19003   vat_json_object_add_uint (node, "tunnel_index",
19004                             ntohl (mp->mt_tunnel_index));
19005   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19006
19007   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19008
19009   fp = mp->mt_paths;
19010   for (i = 0; i < count; i++)
19011     {
19012       vl_api_mpls_fib_path_json_print (node, fp);
19013       fp++;
19014     }
19015 }
19016
19017 static int
19018 api_mpls_tunnel_dump (vat_main_t * vam)
19019 {
19020   vl_api_mpls_tunnel_dump_t *mp;
19021   vl_api_control_ping_t *mp_ping;
19022   u32 sw_if_index = ~0;
19023   int ret;
19024
19025   /* Parse args required to build the message */
19026   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19027     {
19028       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19029         ;
19030     }
19031
19032   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19033
19034   M (MPLS_TUNNEL_DUMP, mp);
19035   mp->sw_if_index = htonl (sw_if_index);
19036   S (mp);
19037
19038   /* Use a control ping for synchronization */
19039   MPING (CONTROL_PING, mp_ping);
19040   S (mp_ping);
19041
19042   W (ret);
19043   return ret;
19044 }
19045
19046 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19047 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19048
19049
19050 static void
19051 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19052 {
19053   vat_main_t *vam = &vat_main;
19054   int count = ntohl (mp->count);
19055   vl_api_fib_path_t *fp;
19056   int i;
19057
19058   print (vam->ofp,
19059          "table-id %d, label %u, ess_bit %u",
19060          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19061   fp = mp->path;
19062   for (i = 0; i < count; i++)
19063     {
19064       vl_api_mpls_fib_path_print (vam, fp);
19065       fp++;
19066     }
19067 }
19068
19069 static void vl_api_mpls_fib_details_t_handler_json
19070   (vl_api_mpls_fib_details_t * mp)
19071 {
19072   vat_main_t *vam = &vat_main;
19073   int count = ntohl (mp->count);
19074   vat_json_node_t *node = NULL;
19075   vl_api_fib_path_t *fp;
19076   int i;
19077
19078   if (VAT_JSON_ARRAY != vam->json_tree.type)
19079     {
19080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19081       vat_json_init_array (&vam->json_tree);
19082     }
19083   node = vat_json_array_add (&vam->json_tree);
19084
19085   vat_json_init_object (node);
19086   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19087   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19088   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19089   vat_json_object_add_uint (node, "path_count", count);
19090   fp = mp->path;
19091   for (i = 0; i < count; i++)
19092     {
19093       vl_api_mpls_fib_path_json_print (node, fp);
19094       fp++;
19095     }
19096 }
19097
19098 static int
19099 api_mpls_fib_dump (vat_main_t * vam)
19100 {
19101   vl_api_mpls_fib_dump_t *mp;
19102   vl_api_control_ping_t *mp_ping;
19103   int ret;
19104
19105   M (MPLS_FIB_DUMP, mp);
19106   S (mp);
19107
19108   /* Use a control ping for synchronization */
19109   MPING (CONTROL_PING, mp_ping);
19110   S (mp_ping);
19111
19112   W (ret);
19113   return ret;
19114 }
19115
19116 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19117 #define vl_api_ip_fib_details_t_print vl_noop_handler
19118
19119 static void
19120 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19121 {
19122   vat_main_t *vam = &vat_main;
19123   int count = ntohl (mp->count);
19124   vl_api_fib_path_t *fp;
19125   int i;
19126
19127   print (vam->ofp,
19128          "table-id %d, prefix %U/%d stats-index %d",
19129          ntohl (mp->table_id), format_ip4_address, mp->address,
19130          mp->address_length, ntohl (mp->stats_index));
19131   fp = mp->path;
19132   for (i = 0; i < count; i++)
19133     {
19134       if (fp->afi == IP46_TYPE_IP6)
19135         print (vam->ofp,
19136                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19137                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19138                "next_hop_table %d",
19139                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19140                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19141                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19142       else if (fp->afi == IP46_TYPE_IP4)
19143         print (vam->ofp,
19144                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19145                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19146                "next_hop_table %d",
19147                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19148                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19149                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19150       fp++;
19151     }
19152 }
19153
19154 static void vl_api_ip_fib_details_t_handler_json
19155   (vl_api_ip_fib_details_t * mp)
19156 {
19157   vat_main_t *vam = &vat_main;
19158   int count = ntohl (mp->count);
19159   vat_json_node_t *node = NULL;
19160   struct in_addr ip4;
19161   struct in6_addr ip6;
19162   vl_api_fib_path_t *fp;
19163   int i;
19164
19165   if (VAT_JSON_ARRAY != vam->json_tree.type)
19166     {
19167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19168       vat_json_init_array (&vam->json_tree);
19169     }
19170   node = vat_json_array_add (&vam->json_tree);
19171
19172   vat_json_init_object (node);
19173   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19174   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19175   vat_json_object_add_ip4 (node, "prefix", ip4);
19176   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19177   vat_json_object_add_uint (node, "path_count", count);
19178   fp = mp->path;
19179   for (i = 0; i < count; i++)
19180     {
19181       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19182       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19183       vat_json_object_add_uint (node, "is_local", fp->is_local);
19184       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19185       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19186       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19187       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19188       if (fp->afi == IP46_TYPE_IP4)
19189         {
19190           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19191           vat_json_object_add_ip4 (node, "next_hop", ip4);
19192         }
19193       else if (fp->afi == IP46_TYPE_IP6)
19194         {
19195           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19196           vat_json_object_add_ip6 (node, "next_hop", ip6);
19197         }
19198     }
19199 }
19200
19201 static int
19202 api_ip_fib_dump (vat_main_t * vam)
19203 {
19204   vl_api_ip_fib_dump_t *mp;
19205   vl_api_control_ping_t *mp_ping;
19206   int ret;
19207
19208   M (IP_FIB_DUMP, mp);
19209   S (mp);
19210
19211   /* Use a control ping for synchronization */
19212   MPING (CONTROL_PING, mp_ping);
19213   S (mp_ping);
19214
19215   W (ret);
19216   return ret;
19217 }
19218
19219 static int
19220 api_ip_mfib_dump (vat_main_t * vam)
19221 {
19222   vl_api_ip_mfib_dump_t *mp;
19223   vl_api_control_ping_t *mp_ping;
19224   int ret;
19225
19226   M (IP_MFIB_DUMP, mp);
19227   S (mp);
19228
19229   /* Use a control ping for synchronization */
19230   MPING (CONTROL_PING, mp_ping);
19231   S (mp_ping);
19232
19233   W (ret);
19234   return ret;
19235 }
19236
19237 static void vl_api_ip_neighbor_details_t_handler
19238   (vl_api_ip_neighbor_details_t * mp)
19239 {
19240   vat_main_t *vam = &vat_main;
19241
19242   print (vam->ofp, "%c %U %U",
19243          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19244          format_vl_api_mac_address, &mp->neighbor.mac_address,
19245          format_vl_api_address, &mp->neighbor.ip_address);
19246 }
19247
19248 static void vl_api_ip_neighbor_details_t_handler_json
19249   (vl_api_ip_neighbor_details_t * mp)
19250 {
19251
19252   vat_main_t *vam = &vat_main;
19253   vat_json_node_t *node;
19254
19255   if (VAT_JSON_ARRAY != vam->json_tree.type)
19256     {
19257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19258       vat_json_init_array (&vam->json_tree);
19259     }
19260   node = vat_json_array_add (&vam->json_tree);
19261
19262   vat_json_init_object (node);
19263   vat_json_object_add_string_copy
19264     (node, "flag",
19265      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19266       (u8 *) "static" : (u8 *) "dynamic"));
19267
19268   vat_json_object_add_string_copy (node, "link_layer",
19269                                    format (0, "%U", format_vl_api_mac_address,
19270                                            &mp->neighbor.mac_address));
19271   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19272 }
19273
19274 static int
19275 api_ip_neighbor_dump (vat_main_t * vam)
19276 {
19277   unformat_input_t *i = vam->input;
19278   vl_api_ip_neighbor_dump_t *mp;
19279   vl_api_control_ping_t *mp_ping;
19280   u8 is_ipv6 = 0;
19281   u32 sw_if_index = ~0;
19282   int ret;
19283
19284   /* Parse args required to build the message */
19285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19286     {
19287       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19288         ;
19289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19290         ;
19291       else if (unformat (i, "ip6"))
19292         is_ipv6 = 1;
19293       else
19294         break;
19295     }
19296
19297   if (sw_if_index == ~0)
19298     {
19299       errmsg ("missing interface name or sw_if_index");
19300       return -99;
19301     }
19302
19303   M (IP_NEIGHBOR_DUMP, mp);
19304   mp->is_ipv6 = (u8) is_ipv6;
19305   mp->sw_if_index = ntohl (sw_if_index);
19306   S (mp);
19307
19308   /* Use a control ping for synchronization */
19309   MPING (CONTROL_PING, mp_ping);
19310   S (mp_ping);
19311
19312   W (ret);
19313   return ret;
19314 }
19315
19316 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19317 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19318
19319 static void
19320 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19321 {
19322   vat_main_t *vam = &vat_main;
19323   int count = ntohl (mp->count);
19324   vl_api_fib_path_t *fp;
19325   int i;
19326
19327   print (vam->ofp,
19328          "table-id %d, prefix %U/%d stats-index %d",
19329          ntohl (mp->table_id), format_ip6_address, mp->address,
19330          mp->address_length, ntohl (mp->stats_index));
19331   fp = mp->path;
19332   for (i = 0; i < count; i++)
19333     {
19334       if (fp->afi == IP46_TYPE_IP6)
19335         print (vam->ofp,
19336                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19337                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19338                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19339                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19340                format_ip6_address, fp->next_hop);
19341       else if (fp->afi == IP46_TYPE_IP4)
19342         print (vam->ofp,
19343                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19344                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19345                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19346                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19347                format_ip4_address, fp->next_hop);
19348       fp++;
19349     }
19350 }
19351
19352 static void vl_api_ip6_fib_details_t_handler_json
19353   (vl_api_ip6_fib_details_t * mp)
19354 {
19355   vat_main_t *vam = &vat_main;
19356   int count = ntohl (mp->count);
19357   vat_json_node_t *node = NULL;
19358   struct in_addr ip4;
19359   struct in6_addr ip6;
19360   vl_api_fib_path_t *fp;
19361   int i;
19362
19363   if (VAT_JSON_ARRAY != vam->json_tree.type)
19364     {
19365       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19366       vat_json_init_array (&vam->json_tree);
19367     }
19368   node = vat_json_array_add (&vam->json_tree);
19369
19370   vat_json_init_object (node);
19371   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19372   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19373   vat_json_object_add_ip6 (node, "prefix", ip6);
19374   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19375   vat_json_object_add_uint (node, "path_count", count);
19376   fp = mp->path;
19377   for (i = 0; i < count; i++)
19378     {
19379       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19380       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19381       vat_json_object_add_uint (node, "is_local", fp->is_local);
19382       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19383       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19384       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19385       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19386       if (fp->afi == IP46_TYPE_IP4)
19387         {
19388           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19389           vat_json_object_add_ip4 (node, "next_hop", ip4);
19390         }
19391       else if (fp->afi == IP46_TYPE_IP6)
19392         {
19393           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19394           vat_json_object_add_ip6 (node, "next_hop", ip6);
19395         }
19396     }
19397 }
19398
19399 static int
19400 api_ip6_fib_dump (vat_main_t * vam)
19401 {
19402   vl_api_ip6_fib_dump_t *mp;
19403   vl_api_control_ping_t *mp_ping;
19404   int ret;
19405
19406   M (IP6_FIB_DUMP, mp);
19407   S (mp);
19408
19409   /* Use a control ping for synchronization */
19410   MPING (CONTROL_PING, mp_ping);
19411   S (mp_ping);
19412
19413   W (ret);
19414   return ret;
19415 }
19416
19417 static int
19418 api_ip6_mfib_dump (vat_main_t * vam)
19419 {
19420   vl_api_ip6_mfib_dump_t *mp;
19421   vl_api_control_ping_t *mp_ping;
19422   int ret;
19423
19424   M (IP6_MFIB_DUMP, mp);
19425   S (mp);
19426
19427   /* Use a control ping for synchronization */
19428   MPING (CONTROL_PING, mp_ping);
19429   S (mp_ping);
19430
19431   W (ret);
19432   return ret;
19433 }
19434
19435 int
19436 api_classify_table_ids (vat_main_t * vam)
19437 {
19438   vl_api_classify_table_ids_t *mp;
19439   int ret;
19440
19441   /* Construct the API message */
19442   M (CLASSIFY_TABLE_IDS, mp);
19443   mp->context = 0;
19444
19445   S (mp);
19446   W (ret);
19447   return ret;
19448 }
19449
19450 int
19451 api_classify_table_by_interface (vat_main_t * vam)
19452 {
19453   unformat_input_t *input = vam->input;
19454   vl_api_classify_table_by_interface_t *mp;
19455
19456   u32 sw_if_index = ~0;
19457   int ret;
19458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19459     {
19460       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19461         ;
19462       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19463         ;
19464       else
19465         break;
19466     }
19467   if (sw_if_index == ~0)
19468     {
19469       errmsg ("missing interface name or sw_if_index");
19470       return -99;
19471     }
19472
19473   /* Construct the API message */
19474   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19475   mp->context = 0;
19476   mp->sw_if_index = ntohl (sw_if_index);
19477
19478   S (mp);
19479   W (ret);
19480   return ret;
19481 }
19482
19483 int
19484 api_classify_table_info (vat_main_t * vam)
19485 {
19486   unformat_input_t *input = vam->input;
19487   vl_api_classify_table_info_t *mp;
19488
19489   u32 table_id = ~0;
19490   int ret;
19491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19492     {
19493       if (unformat (input, "table_id %d", &table_id))
19494         ;
19495       else
19496         break;
19497     }
19498   if (table_id == ~0)
19499     {
19500       errmsg ("missing table id");
19501       return -99;
19502     }
19503
19504   /* Construct the API message */
19505   M (CLASSIFY_TABLE_INFO, mp);
19506   mp->context = 0;
19507   mp->table_id = ntohl (table_id);
19508
19509   S (mp);
19510   W (ret);
19511   return ret;
19512 }
19513
19514 int
19515 api_classify_session_dump (vat_main_t * vam)
19516 {
19517   unformat_input_t *input = vam->input;
19518   vl_api_classify_session_dump_t *mp;
19519   vl_api_control_ping_t *mp_ping;
19520
19521   u32 table_id = ~0;
19522   int ret;
19523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19524     {
19525       if (unformat (input, "table_id %d", &table_id))
19526         ;
19527       else
19528         break;
19529     }
19530   if (table_id == ~0)
19531     {
19532       errmsg ("missing table id");
19533       return -99;
19534     }
19535
19536   /* Construct the API message */
19537   M (CLASSIFY_SESSION_DUMP, mp);
19538   mp->context = 0;
19539   mp->table_id = ntohl (table_id);
19540   S (mp);
19541
19542   /* Use a control ping for synchronization */
19543   MPING (CONTROL_PING, mp_ping);
19544   S (mp_ping);
19545
19546   W (ret);
19547   return ret;
19548 }
19549
19550 static void
19551 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19552 {
19553   vat_main_t *vam = &vat_main;
19554
19555   print (vam->ofp, "collector_address %U, collector_port %d, "
19556          "src_address %U, vrf_id %d, path_mtu %u, "
19557          "template_interval %u, udp_checksum %d",
19558          format_ip4_address, mp->collector_address,
19559          ntohs (mp->collector_port),
19560          format_ip4_address, mp->src_address,
19561          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19562          ntohl (mp->template_interval), mp->udp_checksum);
19563
19564   vam->retval = 0;
19565   vam->result_ready = 1;
19566 }
19567
19568 static void
19569   vl_api_ipfix_exporter_details_t_handler_json
19570   (vl_api_ipfix_exporter_details_t * mp)
19571 {
19572   vat_main_t *vam = &vat_main;
19573   vat_json_node_t node;
19574   struct in_addr collector_address;
19575   struct in_addr src_address;
19576
19577   vat_json_init_object (&node);
19578   clib_memcpy (&collector_address, &mp->collector_address,
19579                sizeof (collector_address));
19580   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19581   vat_json_object_add_uint (&node, "collector_port",
19582                             ntohs (mp->collector_port));
19583   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19584   vat_json_object_add_ip4 (&node, "src_address", src_address);
19585   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19586   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19587   vat_json_object_add_uint (&node, "template_interval",
19588                             ntohl (mp->template_interval));
19589   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19590
19591   vat_json_print (vam->ofp, &node);
19592   vat_json_free (&node);
19593   vam->retval = 0;
19594   vam->result_ready = 1;
19595 }
19596
19597 int
19598 api_ipfix_exporter_dump (vat_main_t * vam)
19599 {
19600   vl_api_ipfix_exporter_dump_t *mp;
19601   int ret;
19602
19603   /* Construct the API message */
19604   M (IPFIX_EXPORTER_DUMP, mp);
19605   mp->context = 0;
19606
19607   S (mp);
19608   W (ret);
19609   return ret;
19610 }
19611
19612 static int
19613 api_ipfix_classify_stream_dump (vat_main_t * vam)
19614 {
19615   vl_api_ipfix_classify_stream_dump_t *mp;
19616   int ret;
19617
19618   /* Construct the API message */
19619   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19620   mp->context = 0;
19621
19622   S (mp);
19623   W (ret);
19624   return ret;
19625   /* NOTREACHED */
19626   return 0;
19627 }
19628
19629 static void
19630   vl_api_ipfix_classify_stream_details_t_handler
19631   (vl_api_ipfix_classify_stream_details_t * mp)
19632 {
19633   vat_main_t *vam = &vat_main;
19634   print (vam->ofp, "domain_id %d, src_port %d",
19635          ntohl (mp->domain_id), ntohs (mp->src_port));
19636   vam->retval = 0;
19637   vam->result_ready = 1;
19638 }
19639
19640 static void
19641   vl_api_ipfix_classify_stream_details_t_handler_json
19642   (vl_api_ipfix_classify_stream_details_t * mp)
19643 {
19644   vat_main_t *vam = &vat_main;
19645   vat_json_node_t node;
19646
19647   vat_json_init_object (&node);
19648   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19649   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19650
19651   vat_json_print (vam->ofp, &node);
19652   vat_json_free (&node);
19653   vam->retval = 0;
19654   vam->result_ready = 1;
19655 }
19656
19657 static int
19658 api_ipfix_classify_table_dump (vat_main_t * vam)
19659 {
19660   vl_api_ipfix_classify_table_dump_t *mp;
19661   vl_api_control_ping_t *mp_ping;
19662   int ret;
19663
19664   if (!vam->json_output)
19665     {
19666       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19667              "transport_protocol");
19668     }
19669
19670   /* Construct the API message */
19671   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19672
19673   /* send it... */
19674   S (mp);
19675
19676   /* Use a control ping for synchronization */
19677   MPING (CONTROL_PING, mp_ping);
19678   S (mp_ping);
19679
19680   W (ret);
19681   return ret;
19682 }
19683
19684 static void
19685   vl_api_ipfix_classify_table_details_t_handler
19686   (vl_api_ipfix_classify_table_details_t * mp)
19687 {
19688   vat_main_t *vam = &vat_main;
19689   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19690          mp->transport_protocol);
19691 }
19692
19693 static void
19694   vl_api_ipfix_classify_table_details_t_handler_json
19695   (vl_api_ipfix_classify_table_details_t * mp)
19696 {
19697   vat_json_node_t *node = NULL;
19698   vat_main_t *vam = &vat_main;
19699
19700   if (VAT_JSON_ARRAY != vam->json_tree.type)
19701     {
19702       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19703       vat_json_init_array (&vam->json_tree);
19704     }
19705
19706   node = vat_json_array_add (&vam->json_tree);
19707   vat_json_init_object (node);
19708
19709   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19710   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19711   vat_json_object_add_uint (node, "transport_protocol",
19712                             mp->transport_protocol);
19713 }
19714
19715 static int
19716 api_sw_interface_span_enable_disable (vat_main_t * vam)
19717 {
19718   unformat_input_t *i = vam->input;
19719   vl_api_sw_interface_span_enable_disable_t *mp;
19720   u32 src_sw_if_index = ~0;
19721   u32 dst_sw_if_index = ~0;
19722   u8 state = 3;
19723   int ret;
19724   u8 is_l2 = 0;
19725
19726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19727     {
19728       if (unformat
19729           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19730         ;
19731       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19732         ;
19733       else
19734         if (unformat
19735             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19736         ;
19737       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19738         ;
19739       else if (unformat (i, "disable"))
19740         state = 0;
19741       else if (unformat (i, "rx"))
19742         state = 1;
19743       else if (unformat (i, "tx"))
19744         state = 2;
19745       else if (unformat (i, "both"))
19746         state = 3;
19747       else if (unformat (i, "l2"))
19748         is_l2 = 1;
19749       else
19750         break;
19751     }
19752
19753   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19754
19755   mp->sw_if_index_from = htonl (src_sw_if_index);
19756   mp->sw_if_index_to = htonl (dst_sw_if_index);
19757   mp->state = state;
19758   mp->is_l2 = is_l2;
19759
19760   S (mp);
19761   W (ret);
19762   return ret;
19763 }
19764
19765 static void
19766 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19767                                             * mp)
19768 {
19769   vat_main_t *vam = &vat_main;
19770   u8 *sw_if_from_name = 0;
19771   u8 *sw_if_to_name = 0;
19772   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19773   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19774   char *states[] = { "none", "rx", "tx", "both" };
19775   hash_pair_t *p;
19776
19777   /* *INDENT-OFF* */
19778   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19779   ({
19780     if ((u32) p->value[0] == sw_if_index_from)
19781       {
19782         sw_if_from_name = (u8 *)(p->key);
19783         if (sw_if_to_name)
19784           break;
19785       }
19786     if ((u32) p->value[0] == sw_if_index_to)
19787       {
19788         sw_if_to_name = (u8 *)(p->key);
19789         if (sw_if_from_name)
19790           break;
19791       }
19792   }));
19793   /* *INDENT-ON* */
19794   print (vam->ofp, "%20s => %20s (%s) %s",
19795          sw_if_from_name, sw_if_to_name, states[mp->state],
19796          mp->is_l2 ? "l2" : "device");
19797 }
19798
19799 static void
19800   vl_api_sw_interface_span_details_t_handler_json
19801   (vl_api_sw_interface_span_details_t * mp)
19802 {
19803   vat_main_t *vam = &vat_main;
19804   vat_json_node_t *node = NULL;
19805   u8 *sw_if_from_name = 0;
19806   u8 *sw_if_to_name = 0;
19807   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19808   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19809   hash_pair_t *p;
19810
19811   /* *INDENT-OFF* */
19812   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19813   ({
19814     if ((u32) p->value[0] == sw_if_index_from)
19815       {
19816         sw_if_from_name = (u8 *)(p->key);
19817         if (sw_if_to_name)
19818           break;
19819       }
19820     if ((u32) p->value[0] == sw_if_index_to)
19821       {
19822         sw_if_to_name = (u8 *)(p->key);
19823         if (sw_if_from_name)
19824           break;
19825       }
19826   }));
19827   /* *INDENT-ON* */
19828
19829   if (VAT_JSON_ARRAY != vam->json_tree.type)
19830     {
19831       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19832       vat_json_init_array (&vam->json_tree);
19833     }
19834   node = vat_json_array_add (&vam->json_tree);
19835
19836   vat_json_init_object (node);
19837   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19838   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19839   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19840   if (0 != sw_if_to_name)
19841     {
19842       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19843     }
19844   vat_json_object_add_uint (node, "state", mp->state);
19845   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19846 }
19847
19848 static int
19849 api_sw_interface_span_dump (vat_main_t * vam)
19850 {
19851   unformat_input_t *input = vam->input;
19852   vl_api_sw_interface_span_dump_t *mp;
19853   vl_api_control_ping_t *mp_ping;
19854   u8 is_l2 = 0;
19855   int ret;
19856
19857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19858     {
19859       if (unformat (input, "l2"))
19860         is_l2 = 1;
19861       else
19862         break;
19863     }
19864
19865   M (SW_INTERFACE_SPAN_DUMP, mp);
19866   mp->is_l2 = is_l2;
19867   S (mp);
19868
19869   /* Use a control ping for synchronization */
19870   MPING (CONTROL_PING, mp_ping);
19871   S (mp_ping);
19872
19873   W (ret);
19874   return ret;
19875 }
19876
19877 int
19878 api_pg_create_interface (vat_main_t * vam)
19879 {
19880   unformat_input_t *input = vam->input;
19881   vl_api_pg_create_interface_t *mp;
19882
19883   u32 if_id = ~0;
19884   int ret;
19885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19886     {
19887       if (unformat (input, "if_id %d", &if_id))
19888         ;
19889       else
19890         break;
19891     }
19892   if (if_id == ~0)
19893     {
19894       errmsg ("missing pg interface index");
19895       return -99;
19896     }
19897
19898   /* Construct the API message */
19899   M (PG_CREATE_INTERFACE, mp);
19900   mp->context = 0;
19901   mp->interface_id = ntohl (if_id);
19902
19903   S (mp);
19904   W (ret);
19905   return ret;
19906 }
19907
19908 int
19909 api_pg_capture (vat_main_t * vam)
19910 {
19911   unformat_input_t *input = vam->input;
19912   vl_api_pg_capture_t *mp;
19913
19914   u32 if_id = ~0;
19915   u8 enable = 1;
19916   u32 count = 1;
19917   u8 pcap_file_set = 0;
19918   u8 *pcap_file = 0;
19919   int ret;
19920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19921     {
19922       if (unformat (input, "if_id %d", &if_id))
19923         ;
19924       else if (unformat (input, "pcap %s", &pcap_file))
19925         pcap_file_set = 1;
19926       else if (unformat (input, "count %d", &count))
19927         ;
19928       else if (unformat (input, "disable"))
19929         enable = 0;
19930       else
19931         break;
19932     }
19933   if (if_id == ~0)
19934     {
19935       errmsg ("missing pg interface index");
19936       return -99;
19937     }
19938   if (pcap_file_set > 0)
19939     {
19940       if (vec_len (pcap_file) > 255)
19941         {
19942           errmsg ("pcap file name is too long");
19943           return -99;
19944         }
19945     }
19946
19947   u32 name_len = vec_len (pcap_file);
19948   /* Construct the API message */
19949   M (PG_CAPTURE, mp);
19950   mp->context = 0;
19951   mp->interface_id = ntohl (if_id);
19952   mp->is_enabled = enable;
19953   mp->count = ntohl (count);
19954   mp->pcap_name_length = ntohl (name_len);
19955   if (pcap_file_set != 0)
19956     {
19957       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19958     }
19959   vec_free (pcap_file);
19960
19961   S (mp);
19962   W (ret);
19963   return ret;
19964 }
19965
19966 int
19967 api_pg_enable_disable (vat_main_t * vam)
19968 {
19969   unformat_input_t *input = vam->input;
19970   vl_api_pg_enable_disable_t *mp;
19971
19972   u8 enable = 1;
19973   u8 stream_name_set = 0;
19974   u8 *stream_name = 0;
19975   int ret;
19976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (input, "stream %s", &stream_name))
19979         stream_name_set = 1;
19980       else if (unformat (input, "disable"))
19981         enable = 0;
19982       else
19983         break;
19984     }
19985
19986   if (stream_name_set > 0)
19987     {
19988       if (vec_len (stream_name) > 255)
19989         {
19990           errmsg ("stream name too long");
19991           return -99;
19992         }
19993     }
19994
19995   u32 name_len = vec_len (stream_name);
19996   /* Construct the API message */
19997   M (PG_ENABLE_DISABLE, mp);
19998   mp->context = 0;
19999   mp->is_enabled = enable;
20000   if (stream_name_set != 0)
20001     {
20002       mp->stream_name_length = ntohl (name_len);
20003       clib_memcpy (mp->stream_name, stream_name, name_len);
20004     }
20005   vec_free (stream_name);
20006
20007   S (mp);
20008   W (ret);
20009   return ret;
20010 }
20011
20012 int
20013 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20014 {
20015   unformat_input_t *input = vam->input;
20016   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20017
20018   u16 *low_ports = 0;
20019   u16 *high_ports = 0;
20020   u16 this_low;
20021   u16 this_hi;
20022   vl_api_prefix_t prefix;
20023   u32 tmp, tmp2;
20024   u8 prefix_set = 0;
20025   u32 vrf_id = ~0;
20026   u8 is_add = 1;
20027   int ret;
20028
20029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20030     {
20031       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20032         prefix_set = 1;
20033       else if (unformat (input, "vrf %d", &vrf_id))
20034         ;
20035       else if (unformat (input, "del"))
20036         is_add = 0;
20037       else if (unformat (input, "port %d", &tmp))
20038         {
20039           if (tmp == 0 || tmp > 65535)
20040             {
20041               errmsg ("port %d out of range", tmp);
20042               return -99;
20043             }
20044           this_low = tmp;
20045           this_hi = this_low + 1;
20046           vec_add1 (low_ports, this_low);
20047           vec_add1 (high_ports, this_hi);
20048         }
20049       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20050         {
20051           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20052             {
20053               errmsg ("incorrect range parameters");
20054               return -99;
20055             }
20056           this_low = tmp;
20057           /* Note: in debug CLI +1 is added to high before
20058              passing to real fn that does "the work"
20059              (ip_source_and_port_range_check_add_del).
20060              This fn is a wrapper around the binary API fn a
20061              control plane will call, which expects this increment
20062              to have occurred. Hence letting the binary API control
20063              plane fn do the increment for consistency between VAT
20064              and other control planes.
20065            */
20066           this_hi = tmp2;
20067           vec_add1 (low_ports, this_low);
20068           vec_add1 (high_ports, this_hi);
20069         }
20070       else
20071         break;
20072     }
20073
20074   if (prefix_set == 0)
20075     {
20076       errmsg ("<address>/<mask> not specified");
20077       return -99;
20078     }
20079
20080   if (vrf_id == ~0)
20081     {
20082       errmsg ("VRF ID required, not specified");
20083       return -99;
20084     }
20085
20086   if (vrf_id == 0)
20087     {
20088       errmsg
20089         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20090       return -99;
20091     }
20092
20093   if (vec_len (low_ports) == 0)
20094     {
20095       errmsg ("At least one port or port range required");
20096       return -99;
20097     }
20098
20099   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20100
20101   mp->is_add = is_add;
20102
20103   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20104
20105   mp->number_of_ranges = vec_len (low_ports);
20106
20107   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20108   vec_free (low_ports);
20109
20110   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20111   vec_free (high_ports);
20112
20113   mp->vrf_id = ntohl (vrf_id);
20114
20115   S (mp);
20116   W (ret);
20117   return ret;
20118 }
20119
20120 int
20121 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20122 {
20123   unformat_input_t *input = vam->input;
20124   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20125   u32 sw_if_index = ~0;
20126   int vrf_set = 0;
20127   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20128   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20129   u8 is_add = 1;
20130   int ret;
20131
20132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20133     {
20134       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20135         ;
20136       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20137         ;
20138       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20139         vrf_set = 1;
20140       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20141         vrf_set = 1;
20142       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20143         vrf_set = 1;
20144       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20145         vrf_set = 1;
20146       else if (unformat (input, "del"))
20147         is_add = 0;
20148       else
20149         break;
20150     }
20151
20152   if (sw_if_index == ~0)
20153     {
20154       errmsg ("Interface required but not specified");
20155       return -99;
20156     }
20157
20158   if (vrf_set == 0)
20159     {
20160       errmsg ("VRF ID required but not specified");
20161       return -99;
20162     }
20163
20164   if (tcp_out_vrf_id == 0
20165       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20166     {
20167       errmsg
20168         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20169       return -99;
20170     }
20171
20172   /* Construct the API message */
20173   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20174
20175   mp->sw_if_index = ntohl (sw_if_index);
20176   mp->is_add = is_add;
20177   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20178   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20179   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20180   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20181
20182   /* send it... */
20183   S (mp);
20184
20185   /* Wait for a reply... */
20186   W (ret);
20187   return ret;
20188 }
20189
20190 static int
20191 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20192 {
20193   unformat_input_t *i = vam->input;
20194   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20195   u32 local_sa_id = 0;
20196   u32 remote_sa_id = 0;
20197   vl_api_ip4_address_t src_address;
20198   vl_api_ip4_address_t dst_address;
20199   u8 is_add = 1;
20200   int ret;
20201
20202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20203     {
20204       if (unformat (i, "local_sa %d", &local_sa_id))
20205         ;
20206       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20207         ;
20208       else
20209         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20210         ;
20211       else
20212         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20213         ;
20214       else if (unformat (i, "del"))
20215         is_add = 0;
20216       else
20217         {
20218           clib_warning ("parse error '%U'", format_unformat_error, i);
20219           return -99;
20220         }
20221     }
20222
20223   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20224
20225   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20226   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20227   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20228   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20229   mp->is_add = is_add;
20230
20231   S (mp);
20232   W (ret);
20233   return ret;
20234 }
20235
20236 static int
20237 api_set_punt (vat_main_t * vam)
20238 {
20239   unformat_input_t *i = vam->input;
20240   vl_api_address_family_t af;
20241   vl_api_set_punt_t *mp;
20242   u32 protocol = ~0;
20243   u32 port = ~0;
20244   int is_add = 1;
20245   int ret;
20246
20247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20248     {
20249       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20250         ;
20251       else if (unformat (i, "protocol %d", &protocol))
20252         ;
20253       else if (unformat (i, "port %d", &port))
20254         ;
20255       else if (unformat (i, "del"))
20256         is_add = 0;
20257       else
20258         {
20259           clib_warning ("parse error '%U'", format_unformat_error, i);
20260           return -99;
20261         }
20262     }
20263
20264   M (SET_PUNT, mp);
20265
20266   mp->is_add = (u8) is_add;
20267   mp->punt.type = PUNT_API_TYPE_L4;
20268   mp->punt.punt.l4.af = af;
20269   mp->punt.punt.l4.protocol = (u8) protocol;
20270   mp->punt.punt.l4.port = htons ((u16) port);
20271
20272   S (mp);
20273   W (ret);
20274   return ret;
20275 }
20276
20277 static void vl_api_ipsec_gre_tunnel_details_t_handler
20278   (vl_api_ipsec_gre_tunnel_details_t * mp)
20279 {
20280   vat_main_t *vam = &vat_main;
20281
20282   print (vam->ofp, "%11d%15U%15U%14d%14d",
20283          ntohl (mp->tunnel.sw_if_index),
20284          format_vl_api_ip4_address, mp->tunnel.src,
20285          format_vl_api_ip4_address, mp->tunnel.dst,
20286          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20287 }
20288
20289 static void
20290 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20291                                 const char *name,
20292                                 const vl_api_ip4_address_t addr)
20293 {
20294   struct in_addr ip4;
20295
20296   clib_memcpy (&ip4, addr, sizeof (ip4));
20297   vat_json_object_add_ip4 (node, name, ip4);
20298 }
20299
20300 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20301   (vl_api_ipsec_gre_tunnel_details_t * mp)
20302 {
20303   vat_main_t *vam = &vat_main;
20304   vat_json_node_t *node = NULL;
20305
20306   if (VAT_JSON_ARRAY != vam->json_tree.type)
20307     {
20308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20309       vat_json_init_array (&vam->json_tree);
20310     }
20311   node = vat_json_array_add (&vam->json_tree);
20312
20313   vat_json_init_object (node);
20314   vat_json_object_add_uint (node, "sw_if_index",
20315                             ntohl (mp->tunnel.sw_if_index));
20316   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20317   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20318   vat_json_object_add_uint (node, "local_sa_id",
20319                             ntohl (mp->tunnel.local_sa_id));
20320   vat_json_object_add_uint (node, "remote_sa_id",
20321                             ntohl (mp->tunnel.remote_sa_id));
20322 }
20323
20324 static int
20325 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20326 {
20327   unformat_input_t *i = vam->input;
20328   vl_api_ipsec_gre_tunnel_dump_t *mp;
20329   vl_api_control_ping_t *mp_ping;
20330   u32 sw_if_index;
20331   u8 sw_if_index_set = 0;
20332   int ret;
20333
20334   /* Parse args required to build the message */
20335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20336     {
20337       if (unformat (i, "sw_if_index %d", &sw_if_index))
20338         sw_if_index_set = 1;
20339       else
20340         break;
20341     }
20342
20343   if (sw_if_index_set == 0)
20344     {
20345       sw_if_index = ~0;
20346     }
20347
20348   if (!vam->json_output)
20349     {
20350       print (vam->ofp, "%11s%15s%15s%14s%14s",
20351              "sw_if_index", "src_address", "dst_address",
20352              "local_sa_id", "remote_sa_id");
20353     }
20354
20355   /* Get list of gre-tunnel interfaces */
20356   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20357
20358   mp->sw_if_index = htonl (sw_if_index);
20359
20360   S (mp);
20361
20362   /* Use a control ping for synchronization */
20363   MPING (CONTROL_PING, mp_ping);
20364   S (mp_ping);
20365
20366   W (ret);
20367   return ret;
20368 }
20369
20370 static int
20371 api_delete_subif (vat_main_t * vam)
20372 {
20373   unformat_input_t *i = vam->input;
20374   vl_api_delete_subif_t *mp;
20375   u32 sw_if_index = ~0;
20376   int ret;
20377
20378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20379     {
20380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20381         ;
20382       if (unformat (i, "sw_if_index %d", &sw_if_index))
20383         ;
20384       else
20385         break;
20386     }
20387
20388   if (sw_if_index == ~0)
20389     {
20390       errmsg ("missing sw_if_index");
20391       return -99;
20392     }
20393
20394   /* Construct the API message */
20395   M (DELETE_SUBIF, mp);
20396   mp->sw_if_index = ntohl (sw_if_index);
20397
20398   S (mp);
20399   W (ret);
20400   return ret;
20401 }
20402
20403 #define foreach_pbb_vtr_op      \
20404 _("disable",  L2_VTR_DISABLED)  \
20405 _("pop",  L2_VTR_POP_2)         \
20406 _("push",  L2_VTR_PUSH_2)
20407
20408 static int
20409 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20410 {
20411   unformat_input_t *i = vam->input;
20412   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20413   u32 sw_if_index = ~0, vtr_op = ~0;
20414   u16 outer_tag = ~0;
20415   u8 dmac[6], smac[6];
20416   u8 dmac_set = 0, smac_set = 0;
20417   u16 vlanid = 0;
20418   u32 sid = ~0;
20419   u32 tmp;
20420   int ret;
20421
20422   /* Shut up coverity */
20423   clib_memset (dmac, 0, sizeof (dmac));
20424   clib_memset (smac, 0, sizeof (smac));
20425
20426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20427     {
20428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20429         ;
20430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20431         ;
20432       else if (unformat (i, "vtr_op %d", &vtr_op))
20433         ;
20434 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20435       foreach_pbb_vtr_op
20436 #undef _
20437         else if (unformat (i, "translate_pbb_stag"))
20438         {
20439           if (unformat (i, "%d", &tmp))
20440             {
20441               vtr_op = L2_VTR_TRANSLATE_2_1;
20442               outer_tag = tmp;
20443             }
20444           else
20445             {
20446               errmsg
20447                 ("translate_pbb_stag operation requires outer tag definition");
20448               return -99;
20449             }
20450         }
20451       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20452         dmac_set++;
20453       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20454         smac_set++;
20455       else if (unformat (i, "sid %d", &sid))
20456         ;
20457       else if (unformat (i, "vlanid %d", &tmp))
20458         vlanid = tmp;
20459       else
20460         {
20461           clib_warning ("parse error '%U'", format_unformat_error, i);
20462           return -99;
20463         }
20464     }
20465
20466   if ((sw_if_index == ~0) || (vtr_op == ~0))
20467     {
20468       errmsg ("missing sw_if_index or vtr operation");
20469       return -99;
20470     }
20471   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20472       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20473     {
20474       errmsg
20475         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20476       return -99;
20477     }
20478
20479   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20480   mp->sw_if_index = ntohl (sw_if_index);
20481   mp->vtr_op = ntohl (vtr_op);
20482   mp->outer_tag = ntohs (outer_tag);
20483   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20484   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20485   mp->b_vlanid = ntohs (vlanid);
20486   mp->i_sid = ntohl (sid);
20487
20488   S (mp);
20489   W (ret);
20490   return ret;
20491 }
20492
20493 static int
20494 api_flow_classify_set_interface (vat_main_t * vam)
20495 {
20496   unformat_input_t *i = vam->input;
20497   vl_api_flow_classify_set_interface_t *mp;
20498   u32 sw_if_index;
20499   int sw_if_index_set;
20500   u32 ip4_table_index = ~0;
20501   u32 ip6_table_index = ~0;
20502   u8 is_add = 1;
20503   int ret;
20504
20505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20506     {
20507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20508         sw_if_index_set = 1;
20509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20510         sw_if_index_set = 1;
20511       else if (unformat (i, "del"))
20512         is_add = 0;
20513       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20514         ;
20515       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20516         ;
20517       else
20518         {
20519           clib_warning ("parse error '%U'", format_unformat_error, i);
20520           return -99;
20521         }
20522     }
20523
20524   if (sw_if_index_set == 0)
20525     {
20526       errmsg ("missing interface name or sw_if_index");
20527       return -99;
20528     }
20529
20530   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20531
20532   mp->sw_if_index = ntohl (sw_if_index);
20533   mp->ip4_table_index = ntohl (ip4_table_index);
20534   mp->ip6_table_index = ntohl (ip6_table_index);
20535   mp->is_add = is_add;
20536
20537   S (mp);
20538   W (ret);
20539   return ret;
20540 }
20541
20542 static int
20543 api_flow_classify_dump (vat_main_t * vam)
20544 {
20545   unformat_input_t *i = vam->input;
20546   vl_api_flow_classify_dump_t *mp;
20547   vl_api_control_ping_t *mp_ping;
20548   u8 type = FLOW_CLASSIFY_N_TABLES;
20549   int ret;
20550
20551   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20552     ;
20553   else
20554     {
20555       errmsg ("classify table type must be specified");
20556       return -99;
20557     }
20558
20559   if (!vam->json_output)
20560     {
20561       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20562     }
20563
20564   M (FLOW_CLASSIFY_DUMP, mp);
20565   mp->type = type;
20566   /* send it... */
20567   S (mp);
20568
20569   /* Use a control ping for synchronization */
20570   MPING (CONTROL_PING, mp_ping);
20571   S (mp_ping);
20572
20573   /* Wait for a reply... */
20574   W (ret);
20575   return ret;
20576 }
20577
20578 static int
20579 api_feature_enable_disable (vat_main_t * vam)
20580 {
20581   unformat_input_t *i = vam->input;
20582   vl_api_feature_enable_disable_t *mp;
20583   u8 *arc_name = 0;
20584   u8 *feature_name = 0;
20585   u32 sw_if_index = ~0;
20586   u8 enable = 1;
20587   int ret;
20588
20589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20590     {
20591       if (unformat (i, "arc_name %s", &arc_name))
20592         ;
20593       else if (unformat (i, "feature_name %s", &feature_name))
20594         ;
20595       else
20596         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20597         ;
20598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20599         ;
20600       else if (unformat (i, "disable"))
20601         enable = 0;
20602       else
20603         break;
20604     }
20605
20606   if (arc_name == 0)
20607     {
20608       errmsg ("missing arc name");
20609       return -99;
20610     }
20611   if (vec_len (arc_name) > 63)
20612     {
20613       errmsg ("arc name too long");
20614     }
20615
20616   if (feature_name == 0)
20617     {
20618       errmsg ("missing feature name");
20619       return -99;
20620     }
20621   if (vec_len (feature_name) > 63)
20622     {
20623       errmsg ("feature name too long");
20624     }
20625
20626   if (sw_if_index == ~0)
20627     {
20628       errmsg ("missing interface name or sw_if_index");
20629       return -99;
20630     }
20631
20632   /* Construct the API message */
20633   M (FEATURE_ENABLE_DISABLE, mp);
20634   mp->sw_if_index = ntohl (sw_if_index);
20635   mp->enable = enable;
20636   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20637   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20638   vec_free (arc_name);
20639   vec_free (feature_name);
20640
20641   S (mp);
20642   W (ret);
20643   return ret;
20644 }
20645
20646 static int
20647 api_sw_interface_tag_add_del (vat_main_t * vam)
20648 {
20649   unformat_input_t *i = vam->input;
20650   vl_api_sw_interface_tag_add_del_t *mp;
20651   u32 sw_if_index = ~0;
20652   u8 *tag = 0;
20653   u8 enable = 1;
20654   int ret;
20655
20656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20657     {
20658       if (unformat (i, "tag %s", &tag))
20659         ;
20660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20661         ;
20662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20663         ;
20664       else if (unformat (i, "del"))
20665         enable = 0;
20666       else
20667         break;
20668     }
20669
20670   if (sw_if_index == ~0)
20671     {
20672       errmsg ("missing interface name or sw_if_index");
20673       return -99;
20674     }
20675
20676   if (enable && (tag == 0))
20677     {
20678       errmsg ("no tag specified");
20679       return -99;
20680     }
20681
20682   /* Construct the API message */
20683   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20684   mp->sw_if_index = ntohl (sw_if_index);
20685   mp->is_add = enable;
20686   if (enable)
20687     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20688   vec_free (tag);
20689
20690   S (mp);
20691   W (ret);
20692   return ret;
20693 }
20694
20695 static void vl_api_l2_xconnect_details_t_handler
20696   (vl_api_l2_xconnect_details_t * mp)
20697 {
20698   vat_main_t *vam = &vat_main;
20699
20700   print (vam->ofp, "%15d%15d",
20701          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20702 }
20703
20704 static void vl_api_l2_xconnect_details_t_handler_json
20705   (vl_api_l2_xconnect_details_t * mp)
20706 {
20707   vat_main_t *vam = &vat_main;
20708   vat_json_node_t *node = NULL;
20709
20710   if (VAT_JSON_ARRAY != vam->json_tree.type)
20711     {
20712       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20713       vat_json_init_array (&vam->json_tree);
20714     }
20715   node = vat_json_array_add (&vam->json_tree);
20716
20717   vat_json_init_object (node);
20718   vat_json_object_add_uint (node, "rx_sw_if_index",
20719                             ntohl (mp->rx_sw_if_index));
20720   vat_json_object_add_uint (node, "tx_sw_if_index",
20721                             ntohl (mp->tx_sw_if_index));
20722 }
20723
20724 static int
20725 api_l2_xconnect_dump (vat_main_t * vam)
20726 {
20727   vl_api_l2_xconnect_dump_t *mp;
20728   vl_api_control_ping_t *mp_ping;
20729   int ret;
20730
20731   if (!vam->json_output)
20732     {
20733       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20734     }
20735
20736   M (L2_XCONNECT_DUMP, mp);
20737
20738   S (mp);
20739
20740   /* Use a control ping for synchronization */
20741   MPING (CONTROL_PING, mp_ping);
20742   S (mp_ping);
20743
20744   W (ret);
20745   return ret;
20746 }
20747
20748 static int
20749 api_hw_interface_set_mtu (vat_main_t * vam)
20750 {
20751   unformat_input_t *i = vam->input;
20752   vl_api_hw_interface_set_mtu_t *mp;
20753   u32 sw_if_index = ~0;
20754   u32 mtu = 0;
20755   int ret;
20756
20757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20758     {
20759       if (unformat (i, "mtu %d", &mtu))
20760         ;
20761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20762         ;
20763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20764         ;
20765       else
20766         break;
20767     }
20768
20769   if (sw_if_index == ~0)
20770     {
20771       errmsg ("missing interface name or sw_if_index");
20772       return -99;
20773     }
20774
20775   if (mtu == 0)
20776     {
20777       errmsg ("no mtu specified");
20778       return -99;
20779     }
20780
20781   /* Construct the API message */
20782   M (HW_INTERFACE_SET_MTU, mp);
20783   mp->sw_if_index = ntohl (sw_if_index);
20784   mp->mtu = ntohs ((u16) mtu);
20785
20786   S (mp);
20787   W (ret);
20788   return ret;
20789 }
20790
20791 static int
20792 api_p2p_ethernet_add (vat_main_t * vam)
20793 {
20794   unformat_input_t *i = vam->input;
20795   vl_api_p2p_ethernet_add_t *mp;
20796   u32 parent_if_index = ~0;
20797   u32 sub_id = ~0;
20798   u8 remote_mac[6];
20799   u8 mac_set = 0;
20800   int ret;
20801
20802   clib_memset (remote_mac, 0, sizeof (remote_mac));
20803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20804     {
20805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20806         ;
20807       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20808         ;
20809       else
20810         if (unformat
20811             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20812         mac_set++;
20813       else if (unformat (i, "sub_id %d", &sub_id))
20814         ;
20815       else
20816         {
20817           clib_warning ("parse error '%U'", format_unformat_error, i);
20818           return -99;
20819         }
20820     }
20821
20822   if (parent_if_index == ~0)
20823     {
20824       errmsg ("missing interface name or sw_if_index");
20825       return -99;
20826     }
20827   if (mac_set == 0)
20828     {
20829       errmsg ("missing remote mac address");
20830       return -99;
20831     }
20832   if (sub_id == ~0)
20833     {
20834       errmsg ("missing sub-interface id");
20835       return -99;
20836     }
20837
20838   M (P2P_ETHERNET_ADD, mp);
20839   mp->parent_if_index = ntohl (parent_if_index);
20840   mp->subif_id = ntohl (sub_id);
20841   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20842
20843   S (mp);
20844   W (ret);
20845   return ret;
20846 }
20847
20848 static int
20849 api_p2p_ethernet_del (vat_main_t * vam)
20850 {
20851   unformat_input_t *i = vam->input;
20852   vl_api_p2p_ethernet_del_t *mp;
20853   u32 parent_if_index = ~0;
20854   u8 remote_mac[6];
20855   u8 mac_set = 0;
20856   int ret;
20857
20858   clib_memset (remote_mac, 0, sizeof (remote_mac));
20859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20860     {
20861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20862         ;
20863       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20864         ;
20865       else
20866         if (unformat
20867             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20868         mac_set++;
20869       else
20870         {
20871           clib_warning ("parse error '%U'", format_unformat_error, i);
20872           return -99;
20873         }
20874     }
20875
20876   if (parent_if_index == ~0)
20877     {
20878       errmsg ("missing interface name or sw_if_index");
20879       return -99;
20880     }
20881   if (mac_set == 0)
20882     {
20883       errmsg ("missing remote mac address");
20884       return -99;
20885     }
20886
20887   M (P2P_ETHERNET_DEL, mp);
20888   mp->parent_if_index = ntohl (parent_if_index);
20889   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20890
20891   S (mp);
20892   W (ret);
20893   return ret;
20894 }
20895
20896 static int
20897 api_lldp_config (vat_main_t * vam)
20898 {
20899   unformat_input_t *i = vam->input;
20900   vl_api_lldp_config_t *mp;
20901   int tx_hold = 0;
20902   int tx_interval = 0;
20903   u8 *sys_name = NULL;
20904   int ret;
20905
20906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20907     {
20908       if (unformat (i, "system-name %s", &sys_name))
20909         ;
20910       else if (unformat (i, "tx-hold %d", &tx_hold))
20911         ;
20912       else if (unformat (i, "tx-interval %d", &tx_interval))
20913         ;
20914       else
20915         {
20916           clib_warning ("parse error '%U'", format_unformat_error, i);
20917           return -99;
20918         }
20919     }
20920
20921   vec_add1 (sys_name, 0);
20922
20923   M (LLDP_CONFIG, mp);
20924   mp->tx_hold = htonl (tx_hold);
20925   mp->tx_interval = htonl (tx_interval);
20926   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20927   vec_free (sys_name);
20928
20929   S (mp);
20930   W (ret);
20931   return ret;
20932 }
20933
20934 static int
20935 api_sw_interface_set_lldp (vat_main_t * vam)
20936 {
20937   unformat_input_t *i = vam->input;
20938   vl_api_sw_interface_set_lldp_t *mp;
20939   u32 sw_if_index = ~0;
20940   u32 enable = 1;
20941   u8 *port_desc = NULL, *mgmt_oid = NULL;
20942   ip4_address_t ip4_addr;
20943   ip6_address_t ip6_addr;
20944   int ret;
20945
20946   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20947   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20948
20949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20950     {
20951       if (unformat (i, "disable"))
20952         enable = 0;
20953       else
20954         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20955         ;
20956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20957         ;
20958       else if (unformat (i, "port-desc %s", &port_desc))
20959         ;
20960       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20961         ;
20962       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20963         ;
20964       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20965         ;
20966       else
20967         break;
20968     }
20969
20970   if (sw_if_index == ~0)
20971     {
20972       errmsg ("missing interface name or sw_if_index");
20973       return -99;
20974     }
20975
20976   /* Construct the API message */
20977   vec_add1 (port_desc, 0);
20978   vec_add1 (mgmt_oid, 0);
20979   M (SW_INTERFACE_SET_LLDP, mp);
20980   mp->sw_if_index = ntohl (sw_if_index);
20981   mp->enable = enable;
20982   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20983   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20984   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20985   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20986   vec_free (port_desc);
20987   vec_free (mgmt_oid);
20988
20989   S (mp);
20990   W (ret);
20991   return ret;
20992 }
20993
20994 static int
20995 api_tcp_configure_src_addresses (vat_main_t * vam)
20996 {
20997   vl_api_tcp_configure_src_addresses_t *mp;
20998   unformat_input_t *i = vam->input;
20999   ip4_address_t v4first, v4last;
21000   ip6_address_t v6first, v6last;
21001   u8 range_set = 0;
21002   u32 vrf_id = 0;
21003   int ret;
21004
21005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21006     {
21007       if (unformat (i, "%U - %U",
21008                     unformat_ip4_address, &v4first,
21009                     unformat_ip4_address, &v4last))
21010         {
21011           if (range_set)
21012             {
21013               errmsg ("one range per message (range already set)");
21014               return -99;
21015             }
21016           range_set = 1;
21017         }
21018       else if (unformat (i, "%U - %U",
21019                          unformat_ip6_address, &v6first,
21020                          unformat_ip6_address, &v6last))
21021         {
21022           if (range_set)
21023             {
21024               errmsg ("one range per message (range already set)");
21025               return -99;
21026             }
21027           range_set = 2;
21028         }
21029       else if (unformat (i, "vrf %d", &vrf_id))
21030         ;
21031       else
21032         break;
21033     }
21034
21035   if (range_set == 0)
21036     {
21037       errmsg ("address range not set");
21038       return -99;
21039     }
21040
21041   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21042   mp->vrf_id = ntohl (vrf_id);
21043   /* ipv6? */
21044   if (range_set == 2)
21045     {
21046       mp->is_ipv6 = 1;
21047       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21048       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21049     }
21050   else
21051     {
21052       mp->is_ipv6 = 0;
21053       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21054       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21055     }
21056   S (mp);
21057   W (ret);
21058   return ret;
21059 }
21060
21061 static void vl_api_app_namespace_add_del_reply_t_handler
21062   (vl_api_app_namespace_add_del_reply_t * mp)
21063 {
21064   vat_main_t *vam = &vat_main;
21065   i32 retval = ntohl (mp->retval);
21066   if (vam->async_mode)
21067     {
21068       vam->async_errors += (retval < 0);
21069     }
21070   else
21071     {
21072       vam->retval = retval;
21073       if (retval == 0)
21074         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21075       vam->result_ready = 1;
21076     }
21077 }
21078
21079 static void vl_api_app_namespace_add_del_reply_t_handler_json
21080   (vl_api_app_namespace_add_del_reply_t * mp)
21081 {
21082   vat_main_t *vam = &vat_main;
21083   vat_json_node_t node;
21084
21085   vat_json_init_object (&node);
21086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21087   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21088
21089   vat_json_print (vam->ofp, &node);
21090   vat_json_free (&node);
21091
21092   vam->retval = ntohl (mp->retval);
21093   vam->result_ready = 1;
21094 }
21095
21096 static int
21097 api_app_namespace_add_del (vat_main_t * vam)
21098 {
21099   vl_api_app_namespace_add_del_t *mp;
21100   unformat_input_t *i = vam->input;
21101   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21102   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21103   u64 secret;
21104   int ret;
21105
21106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21107     {
21108       if (unformat (i, "id %_%v%_", &ns_id))
21109         ;
21110       else if (unformat (i, "secret %lu", &secret))
21111         secret_set = 1;
21112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21113         sw_if_index_set = 1;
21114       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21115         ;
21116       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21117         ;
21118       else
21119         break;
21120     }
21121   if (!ns_id || !secret_set || !sw_if_index_set)
21122     {
21123       errmsg ("namespace id, secret and sw_if_index must be set");
21124       return -99;
21125     }
21126   if (vec_len (ns_id) > 64)
21127     {
21128       errmsg ("namespace id too long");
21129       return -99;
21130     }
21131   M (APP_NAMESPACE_ADD_DEL, mp);
21132
21133   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21134   mp->namespace_id_len = vec_len (ns_id);
21135   mp->secret = clib_host_to_net_u64 (secret);
21136   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21137   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21138   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21139   vec_free (ns_id);
21140   S (mp);
21141   W (ret);
21142   return ret;
21143 }
21144
21145 static int
21146 api_sock_init_shm (vat_main_t * vam)
21147 {
21148 #if VPP_API_TEST_BUILTIN == 0
21149   unformat_input_t *i = vam->input;
21150   vl_api_shm_elem_config_t *config = 0;
21151   u64 size = 64 << 20;
21152   int rv;
21153
21154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21155     {
21156       if (unformat (i, "size %U", unformat_memory_size, &size))
21157         ;
21158       else
21159         break;
21160     }
21161
21162   /*
21163    * Canned custom ring allocator config.
21164    * Should probably parse all of this
21165    */
21166   vec_validate (config, 6);
21167   config[0].type = VL_API_VLIB_RING;
21168   config[0].size = 256;
21169   config[0].count = 32;
21170
21171   config[1].type = VL_API_VLIB_RING;
21172   config[1].size = 1024;
21173   config[1].count = 16;
21174
21175   config[2].type = VL_API_VLIB_RING;
21176   config[2].size = 4096;
21177   config[2].count = 2;
21178
21179   config[3].type = VL_API_CLIENT_RING;
21180   config[3].size = 256;
21181   config[3].count = 32;
21182
21183   config[4].type = VL_API_CLIENT_RING;
21184   config[4].size = 1024;
21185   config[4].count = 16;
21186
21187   config[5].type = VL_API_CLIENT_RING;
21188   config[5].size = 4096;
21189   config[5].count = 2;
21190
21191   config[6].type = VL_API_QUEUE;
21192   config[6].count = 128;
21193   config[6].size = sizeof (uword);
21194
21195   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21196   if (!rv)
21197     vam->client_index_invalid = 1;
21198   return rv;
21199 #else
21200   return -99;
21201 #endif
21202 }
21203
21204 static int
21205 api_dns_enable_disable (vat_main_t * vam)
21206 {
21207   unformat_input_t *line_input = vam->input;
21208   vl_api_dns_enable_disable_t *mp;
21209   u8 enable_disable = 1;
21210   int ret;
21211
21212   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21213     {
21214       if (unformat (line_input, "disable"))
21215         enable_disable = 0;
21216       if (unformat (line_input, "enable"))
21217         enable_disable = 1;
21218       else
21219         break;
21220     }
21221
21222   /* Construct the API message */
21223   M (DNS_ENABLE_DISABLE, mp);
21224   mp->enable = enable_disable;
21225
21226   /* send it... */
21227   S (mp);
21228   /* Wait for the reply */
21229   W (ret);
21230   return ret;
21231 }
21232
21233 static int
21234 api_dns_resolve_name (vat_main_t * vam)
21235 {
21236   unformat_input_t *line_input = vam->input;
21237   vl_api_dns_resolve_name_t *mp;
21238   u8 *name = 0;
21239   int ret;
21240
21241   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21242     {
21243       if (unformat (line_input, "%s", &name))
21244         ;
21245       else
21246         break;
21247     }
21248
21249   if (vec_len (name) > 127)
21250     {
21251       errmsg ("name too long");
21252       return -99;
21253     }
21254
21255   /* Construct the API message */
21256   M (DNS_RESOLVE_NAME, mp);
21257   memcpy (mp->name, name, vec_len (name));
21258   vec_free (name);
21259
21260   /* send it... */
21261   S (mp);
21262   /* Wait for the reply */
21263   W (ret);
21264   return ret;
21265 }
21266
21267 static int
21268 api_dns_resolve_ip (vat_main_t * vam)
21269 {
21270   unformat_input_t *line_input = vam->input;
21271   vl_api_dns_resolve_ip_t *mp;
21272   int is_ip6 = -1;
21273   ip4_address_t addr4;
21274   ip6_address_t addr6;
21275   int ret;
21276
21277   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21278     {
21279       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21280         is_ip6 = 1;
21281       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21282         is_ip6 = 0;
21283       else
21284         break;
21285     }
21286
21287   if (is_ip6 == -1)
21288     {
21289       errmsg ("missing address");
21290       return -99;
21291     }
21292
21293   /* Construct the API message */
21294   M (DNS_RESOLVE_IP, mp);
21295   mp->is_ip6 = is_ip6;
21296   if (is_ip6)
21297     memcpy (mp->address, &addr6, sizeof (addr6));
21298   else
21299     memcpy (mp->address, &addr4, sizeof (addr4));
21300
21301   /* send it... */
21302   S (mp);
21303   /* Wait for the reply */
21304   W (ret);
21305   return ret;
21306 }
21307
21308 static int
21309 api_dns_name_server_add_del (vat_main_t * vam)
21310 {
21311   unformat_input_t *i = vam->input;
21312   vl_api_dns_name_server_add_del_t *mp;
21313   u8 is_add = 1;
21314   ip6_address_t ip6_server;
21315   ip4_address_t ip4_server;
21316   int ip6_set = 0;
21317   int ip4_set = 0;
21318   int ret = 0;
21319
21320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21321     {
21322       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21323         ip6_set = 1;
21324       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21325         ip4_set = 1;
21326       else if (unformat (i, "del"))
21327         is_add = 0;
21328       else
21329         {
21330           clib_warning ("parse error '%U'", format_unformat_error, i);
21331           return -99;
21332         }
21333     }
21334
21335   if (ip4_set && ip6_set)
21336     {
21337       errmsg ("Only one server address allowed per message");
21338       return -99;
21339     }
21340   if ((ip4_set + ip6_set) == 0)
21341     {
21342       errmsg ("Server address required");
21343       return -99;
21344     }
21345
21346   /* Construct the API message */
21347   M (DNS_NAME_SERVER_ADD_DEL, mp);
21348
21349   if (ip6_set)
21350     {
21351       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21352       mp->is_ip6 = 1;
21353     }
21354   else
21355     {
21356       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21357       mp->is_ip6 = 0;
21358     }
21359
21360   mp->is_add = is_add;
21361
21362   /* send it... */
21363   S (mp);
21364
21365   /* Wait for a reply, return good/bad news  */
21366   W (ret);
21367   return ret;
21368 }
21369
21370 static void
21371 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21372 {
21373   vat_main_t *vam = &vat_main;
21374
21375   if (mp->is_ip4)
21376     {
21377       print (vam->ofp,
21378              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21379              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21380              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21381              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21382              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21383              clib_net_to_host_u32 (mp->action_index), mp->tag);
21384     }
21385   else
21386     {
21387       print (vam->ofp,
21388              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21389              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21390              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21391              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21392              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21393              clib_net_to_host_u32 (mp->action_index), mp->tag);
21394     }
21395 }
21396
21397 static void
21398 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21399                                              mp)
21400 {
21401   vat_main_t *vam = &vat_main;
21402   vat_json_node_t *node = NULL;
21403   struct in6_addr ip6;
21404   struct in_addr ip4;
21405
21406   if (VAT_JSON_ARRAY != vam->json_tree.type)
21407     {
21408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21409       vat_json_init_array (&vam->json_tree);
21410     }
21411   node = vat_json_array_add (&vam->json_tree);
21412   vat_json_init_object (node);
21413
21414   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21415   vat_json_object_add_uint (node, "appns_index",
21416                             clib_net_to_host_u32 (mp->appns_index));
21417   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21418   vat_json_object_add_uint (node, "scope", mp->scope);
21419   vat_json_object_add_uint (node, "action_index",
21420                             clib_net_to_host_u32 (mp->action_index));
21421   vat_json_object_add_uint (node, "lcl_port",
21422                             clib_net_to_host_u16 (mp->lcl_port));
21423   vat_json_object_add_uint (node, "rmt_port",
21424                             clib_net_to_host_u16 (mp->rmt_port));
21425   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21426   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21427   vat_json_object_add_string_copy (node, "tag", mp->tag);
21428   if (mp->is_ip4)
21429     {
21430       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21431       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21432       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21433       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21434     }
21435   else
21436     {
21437       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21438       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21439       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21440       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21441     }
21442 }
21443
21444 static int
21445 api_session_rule_add_del (vat_main_t * vam)
21446 {
21447   vl_api_session_rule_add_del_t *mp;
21448   unformat_input_t *i = vam->input;
21449   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21450   u32 appns_index = 0, scope = 0;
21451   ip4_address_t lcl_ip4, rmt_ip4;
21452   ip6_address_t lcl_ip6, rmt_ip6;
21453   u8 is_ip4 = 1, conn_set = 0;
21454   u8 is_add = 1, *tag = 0;
21455   int ret;
21456
21457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21458     {
21459       if (unformat (i, "del"))
21460         is_add = 0;
21461       else if (unformat (i, "add"))
21462         ;
21463       else if (unformat (i, "proto tcp"))
21464         proto = 0;
21465       else if (unformat (i, "proto udp"))
21466         proto = 1;
21467       else if (unformat (i, "appns %d", &appns_index))
21468         ;
21469       else if (unformat (i, "scope %d", &scope))
21470         ;
21471       else if (unformat (i, "tag %_%v%_", &tag))
21472         ;
21473       else
21474         if (unformat
21475             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21476              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21477              &rmt_port))
21478         {
21479           is_ip4 = 1;
21480           conn_set = 1;
21481         }
21482       else
21483         if (unformat
21484             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21485              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21486              &rmt_port))
21487         {
21488           is_ip4 = 0;
21489           conn_set = 1;
21490         }
21491       else if (unformat (i, "action %d", &action))
21492         ;
21493       else
21494         break;
21495     }
21496   if (proto == ~0 || !conn_set || action == ~0)
21497     {
21498       errmsg ("transport proto, connection and action must be set");
21499       return -99;
21500     }
21501
21502   if (scope > 3)
21503     {
21504       errmsg ("scope should be 0-3");
21505       return -99;
21506     }
21507
21508   M (SESSION_RULE_ADD_DEL, mp);
21509
21510   mp->is_ip4 = is_ip4;
21511   mp->transport_proto = proto;
21512   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21513   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21514   mp->lcl_plen = lcl_plen;
21515   mp->rmt_plen = rmt_plen;
21516   mp->action_index = clib_host_to_net_u32 (action);
21517   mp->appns_index = clib_host_to_net_u32 (appns_index);
21518   mp->scope = scope;
21519   mp->is_add = is_add;
21520   if (is_ip4)
21521     {
21522       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21523       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21524     }
21525   else
21526     {
21527       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21528       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21529     }
21530   if (tag)
21531     {
21532       clib_memcpy (mp->tag, tag, vec_len (tag));
21533       vec_free (tag);
21534     }
21535
21536   S (mp);
21537   W (ret);
21538   return ret;
21539 }
21540
21541 static int
21542 api_session_rules_dump (vat_main_t * vam)
21543 {
21544   vl_api_session_rules_dump_t *mp;
21545   vl_api_control_ping_t *mp_ping;
21546   int ret;
21547
21548   if (!vam->json_output)
21549     {
21550       print (vam->ofp, "%=20s", "Session Rules");
21551     }
21552
21553   M (SESSION_RULES_DUMP, mp);
21554   /* send it... */
21555   S (mp);
21556
21557   /* Use a control ping for synchronization */
21558   MPING (CONTROL_PING, mp_ping);
21559   S (mp_ping);
21560
21561   /* Wait for a reply... */
21562   W (ret);
21563   return ret;
21564 }
21565
21566 static int
21567 api_ip_container_proxy_add_del (vat_main_t * vam)
21568 {
21569   vl_api_ip_container_proxy_add_del_t *mp;
21570   unformat_input_t *i = vam->input;
21571   u32 sw_if_index = ~0;
21572   vl_api_prefix_t pfx = { };
21573   u8 is_add = 1;
21574   int ret;
21575
21576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21577     {
21578       if (unformat (i, "del"))
21579         is_add = 0;
21580       else if (unformat (i, "add"))
21581         ;
21582       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21583         ;
21584       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21585         ;
21586       else
21587         break;
21588     }
21589   if (sw_if_index == ~0 || pfx.address_length == 0)
21590     {
21591       errmsg ("address and sw_if_index must be set");
21592       return -99;
21593     }
21594
21595   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21596
21597   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21598   mp->is_add = is_add;
21599   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21600
21601   S (mp);
21602   W (ret);
21603   return ret;
21604 }
21605
21606 static int
21607 api_qos_record_enable_disable (vat_main_t * vam)
21608 {
21609   unformat_input_t *i = vam->input;
21610   vl_api_qos_record_enable_disable_t *mp;
21611   u32 sw_if_index, qs = 0xff;
21612   u8 sw_if_index_set = 0;
21613   u8 enable = 1;
21614   int ret;
21615
21616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21617     {
21618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21619         sw_if_index_set = 1;
21620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21621         sw_if_index_set = 1;
21622       else if (unformat (i, "%U", unformat_qos_source, &qs))
21623         ;
21624       else if (unformat (i, "disable"))
21625         enable = 0;
21626       else
21627         {
21628           clib_warning ("parse error '%U'", format_unformat_error, i);
21629           return -99;
21630         }
21631     }
21632
21633   if (sw_if_index_set == 0)
21634     {
21635       errmsg ("missing interface name or sw_if_index");
21636       return -99;
21637     }
21638   if (qs == 0xff)
21639     {
21640       errmsg ("input location must be specified");
21641       return -99;
21642     }
21643
21644   M (QOS_RECORD_ENABLE_DISABLE, mp);
21645
21646   mp->sw_if_index = ntohl (sw_if_index);
21647   mp->input_source = qs;
21648   mp->enable = enable;
21649
21650   S (mp);
21651   W (ret);
21652   return ret;
21653 }
21654
21655
21656 static int
21657 q_or_quit (vat_main_t * vam)
21658 {
21659 #if VPP_API_TEST_BUILTIN == 0
21660   longjmp (vam->jump_buf, 1);
21661 #endif
21662   return 0;                     /* not so much */
21663 }
21664
21665 static int
21666 q (vat_main_t * vam)
21667 {
21668   return q_or_quit (vam);
21669 }
21670
21671 static int
21672 quit (vat_main_t * vam)
21673 {
21674   return q_or_quit (vam);
21675 }
21676
21677 static int
21678 comment (vat_main_t * vam)
21679 {
21680   return 0;
21681 }
21682
21683 static int
21684 statseg (vat_main_t * vam)
21685 {
21686   ssvm_private_t *ssvmp = &vam->stat_segment;
21687   ssvm_shared_header_t *shared_header = ssvmp->sh;
21688   vlib_counter_t **counters;
21689   u64 thread0_index1_packets;
21690   u64 thread0_index1_bytes;
21691   f64 vector_rate, input_rate;
21692   uword *p;
21693
21694   uword *counter_vector_by_name;
21695   if (vam->stat_segment_lockp == 0)
21696     {
21697       errmsg ("Stat segment not mapped...");
21698       return -99;
21699     }
21700
21701   /* look up "/if/rx for sw_if_index 1 as a test */
21702
21703   clib_spinlock_lock (vam->stat_segment_lockp);
21704
21705   counter_vector_by_name = (uword *) shared_header->opaque[1];
21706
21707   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21708   if (p == 0)
21709     {
21710       clib_spinlock_unlock (vam->stat_segment_lockp);
21711       errmsg ("/if/tx not found?");
21712       return -99;
21713     }
21714
21715   /* Fish per-thread vector of combined counters from shared memory */
21716   counters = (vlib_counter_t **) p[0];
21717
21718   if (vec_len (counters[0]) < 2)
21719     {
21720       clib_spinlock_unlock (vam->stat_segment_lockp);
21721       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21722       return -99;
21723     }
21724
21725   /* Read thread 0 sw_if_index 1 counter */
21726   thread0_index1_packets = counters[0][1].packets;
21727   thread0_index1_bytes = counters[0][1].bytes;
21728
21729   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21730   if (p == 0)
21731     {
21732       clib_spinlock_unlock (vam->stat_segment_lockp);
21733       errmsg ("vector_rate not found?");
21734       return -99;
21735     }
21736
21737   vector_rate = *(f64 *) (p[0]);
21738   p = hash_get_mem (counter_vector_by_name, "input_rate");
21739   if (p == 0)
21740     {
21741       clib_spinlock_unlock (vam->stat_segment_lockp);
21742       errmsg ("input_rate not found?");
21743       return -99;
21744     }
21745   input_rate = *(f64 *) (p[0]);
21746
21747   clib_spinlock_unlock (vam->stat_segment_lockp);
21748
21749   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21750          vector_rate, input_rate);
21751   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21752          thread0_index1_packets, thread0_index1_bytes);
21753
21754   return 0;
21755 }
21756
21757 static int
21758 cmd_cmp (void *a1, void *a2)
21759 {
21760   u8 **c1 = a1;
21761   u8 **c2 = a2;
21762
21763   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21764 }
21765
21766 static int
21767 help (vat_main_t * vam)
21768 {
21769   u8 **cmds = 0;
21770   u8 *name = 0;
21771   hash_pair_t *p;
21772   unformat_input_t *i = vam->input;
21773   int j;
21774
21775   if (unformat (i, "%s", &name))
21776     {
21777       uword *hs;
21778
21779       vec_add1 (name, 0);
21780
21781       hs = hash_get_mem (vam->help_by_name, name);
21782       if (hs)
21783         print (vam->ofp, "usage: %s %s", name, hs[0]);
21784       else
21785         print (vam->ofp, "No such msg / command '%s'", name);
21786       vec_free (name);
21787       return 0;
21788     }
21789
21790   print (vam->ofp, "Help is available for the following:");
21791
21792     /* *INDENT-OFF* */
21793     hash_foreach_pair (p, vam->function_by_name,
21794     ({
21795       vec_add1 (cmds, (u8 *)(p->key));
21796     }));
21797     /* *INDENT-ON* */
21798
21799   vec_sort_with_function (cmds, cmd_cmp);
21800
21801   for (j = 0; j < vec_len (cmds); j++)
21802     print (vam->ofp, "%s", cmds[j]);
21803
21804   vec_free (cmds);
21805   return 0;
21806 }
21807
21808 static int
21809 set (vat_main_t * vam)
21810 {
21811   u8 *name = 0, *value = 0;
21812   unformat_input_t *i = vam->input;
21813
21814   if (unformat (i, "%s", &name))
21815     {
21816       /* The input buffer is a vector, not a string. */
21817       value = vec_dup (i->buffer);
21818       vec_delete (value, i->index, 0);
21819       /* Almost certainly has a trailing newline */
21820       if (value[vec_len (value) - 1] == '\n')
21821         value[vec_len (value) - 1] = 0;
21822       /* Make sure it's a proper string, one way or the other */
21823       vec_add1 (value, 0);
21824       (void) clib_macro_set_value (&vam->macro_main,
21825                                    (char *) name, (char *) value);
21826     }
21827   else
21828     errmsg ("usage: set <name> <value>");
21829
21830   vec_free (name);
21831   vec_free (value);
21832   return 0;
21833 }
21834
21835 static int
21836 unset (vat_main_t * vam)
21837 {
21838   u8 *name = 0;
21839
21840   if (unformat (vam->input, "%s", &name))
21841     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21842       errmsg ("unset: %s wasn't set", name);
21843   vec_free (name);
21844   return 0;
21845 }
21846
21847 typedef struct
21848 {
21849   u8 *name;
21850   u8 *value;
21851 } macro_sort_t;
21852
21853
21854 static int
21855 macro_sort_cmp (void *a1, void *a2)
21856 {
21857   macro_sort_t *s1 = a1;
21858   macro_sort_t *s2 = a2;
21859
21860   return strcmp ((char *) (s1->name), (char *) (s2->name));
21861 }
21862
21863 static int
21864 dump_macro_table (vat_main_t * vam)
21865 {
21866   macro_sort_t *sort_me = 0, *sm;
21867   int i;
21868   hash_pair_t *p;
21869
21870     /* *INDENT-OFF* */
21871     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21872     ({
21873       vec_add2 (sort_me, sm, 1);
21874       sm->name = (u8 *)(p->key);
21875       sm->value = (u8 *) (p->value[0]);
21876     }));
21877     /* *INDENT-ON* */
21878
21879   vec_sort_with_function (sort_me, macro_sort_cmp);
21880
21881   if (vec_len (sort_me))
21882     print (vam->ofp, "%-15s%s", "Name", "Value");
21883   else
21884     print (vam->ofp, "The macro table is empty...");
21885
21886   for (i = 0; i < vec_len (sort_me); i++)
21887     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21888   return 0;
21889 }
21890
21891 static int
21892 dump_node_table (vat_main_t * vam)
21893 {
21894   int i, j;
21895   vlib_node_t *node, *next_node;
21896
21897   if (vec_len (vam->graph_nodes) == 0)
21898     {
21899       print (vam->ofp, "Node table empty, issue get_node_graph...");
21900       return 0;
21901     }
21902
21903   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21904     {
21905       node = vam->graph_nodes[0][i];
21906       print (vam->ofp, "[%d] %s", i, node->name);
21907       for (j = 0; j < vec_len (node->next_nodes); j++)
21908         {
21909           if (node->next_nodes[j] != ~0)
21910             {
21911               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21912               print (vam->ofp, "  [%d] %s", j, next_node->name);
21913             }
21914         }
21915     }
21916   return 0;
21917 }
21918
21919 static int
21920 value_sort_cmp (void *a1, void *a2)
21921 {
21922   name_sort_t *n1 = a1;
21923   name_sort_t *n2 = a2;
21924
21925   if (n1->value < n2->value)
21926     return -1;
21927   if (n1->value > n2->value)
21928     return 1;
21929   return 0;
21930 }
21931
21932
21933 static int
21934 dump_msg_api_table (vat_main_t * vam)
21935 {
21936   api_main_t *am = &api_main;
21937   name_sort_t *nses = 0, *ns;
21938   hash_pair_t *hp;
21939   int i;
21940
21941   /* *INDENT-OFF* */
21942   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21943   ({
21944     vec_add2 (nses, ns, 1);
21945     ns->name = (u8 *)(hp->key);
21946     ns->value = (u32) hp->value[0];
21947   }));
21948   /* *INDENT-ON* */
21949
21950   vec_sort_with_function (nses, value_sort_cmp);
21951
21952   for (i = 0; i < vec_len (nses); i++)
21953     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21954   vec_free (nses);
21955   return 0;
21956 }
21957
21958 static int
21959 get_msg_id (vat_main_t * vam)
21960 {
21961   u8 *name_and_crc;
21962   u32 message_index;
21963
21964   if (unformat (vam->input, "%s", &name_and_crc))
21965     {
21966       message_index = vl_msg_api_get_msg_index (name_and_crc);
21967       if (message_index == ~0)
21968         {
21969           print (vam->ofp, " '%s' not found", name_and_crc);
21970           return 0;
21971         }
21972       print (vam->ofp, " '%s' has message index %d",
21973              name_and_crc, message_index);
21974       return 0;
21975     }
21976   errmsg ("name_and_crc required...");
21977   return 0;
21978 }
21979
21980 static int
21981 search_node_table (vat_main_t * vam)
21982 {
21983   unformat_input_t *line_input = vam->input;
21984   u8 *node_to_find;
21985   int j;
21986   vlib_node_t *node, *next_node;
21987   uword *p;
21988
21989   if (vam->graph_node_index_by_name == 0)
21990     {
21991       print (vam->ofp, "Node table empty, issue get_node_graph...");
21992       return 0;
21993     }
21994
21995   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21996     {
21997       if (unformat (line_input, "%s", &node_to_find))
21998         {
21999           vec_add1 (node_to_find, 0);
22000           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22001           if (p == 0)
22002             {
22003               print (vam->ofp, "%s not found...", node_to_find);
22004               goto out;
22005             }
22006           node = vam->graph_nodes[0][p[0]];
22007           print (vam->ofp, "[%d] %s", p[0], node->name);
22008           for (j = 0; j < vec_len (node->next_nodes); j++)
22009             {
22010               if (node->next_nodes[j] != ~0)
22011                 {
22012                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22013                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22014                 }
22015             }
22016         }
22017
22018       else
22019         {
22020           clib_warning ("parse error '%U'", format_unformat_error,
22021                         line_input);
22022           return -99;
22023         }
22024
22025     out:
22026       vec_free (node_to_find);
22027
22028     }
22029
22030   return 0;
22031 }
22032
22033
22034 static int
22035 script (vat_main_t * vam)
22036 {
22037 #if (VPP_API_TEST_BUILTIN==0)
22038   u8 *s = 0;
22039   char *save_current_file;
22040   unformat_input_t save_input;
22041   jmp_buf save_jump_buf;
22042   u32 save_line_number;
22043
22044   FILE *new_fp, *save_ifp;
22045
22046   if (unformat (vam->input, "%s", &s))
22047     {
22048       new_fp = fopen ((char *) s, "r");
22049       if (new_fp == 0)
22050         {
22051           errmsg ("Couldn't open script file %s", s);
22052           vec_free (s);
22053           return -99;
22054         }
22055     }
22056   else
22057     {
22058       errmsg ("Missing script name");
22059       return -99;
22060     }
22061
22062   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22063   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22064   save_ifp = vam->ifp;
22065   save_line_number = vam->input_line_number;
22066   save_current_file = (char *) vam->current_file;
22067
22068   vam->input_line_number = 0;
22069   vam->ifp = new_fp;
22070   vam->current_file = s;
22071   do_one_file (vam);
22072
22073   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22074   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22075   vam->ifp = save_ifp;
22076   vam->input_line_number = save_line_number;
22077   vam->current_file = (u8 *) save_current_file;
22078   vec_free (s);
22079
22080   return 0;
22081 #else
22082   clib_warning ("use the exec command...");
22083   return -99;
22084 #endif
22085 }
22086
22087 static int
22088 echo (vat_main_t * vam)
22089 {
22090   print (vam->ofp, "%v", vam->input->buffer);
22091   return 0;
22092 }
22093
22094 /* List of API message constructors, CLI names map to api_xxx */
22095 #define foreach_vpe_api_msg                                             \
22096 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22097 _(sw_interface_dump,"")                                                 \
22098 _(sw_interface_set_flags,                                               \
22099   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22100 _(sw_interface_add_del_address,                                         \
22101   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22102 _(sw_interface_set_rx_mode,                                             \
22103   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22104 _(sw_interface_set_rx_placement,                                        \
22105   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22106 _(sw_interface_rx_placement_dump,                                       \
22107   "[<intfc> | sw_if_index <id>]")                                         \
22108 _(sw_interface_set_table,                                               \
22109   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22110 _(sw_interface_set_mpls_enable,                                         \
22111   "<intfc> | sw_if_index [disable | dis]")                              \
22112 _(sw_interface_set_vpath,                                               \
22113   "<intfc> | sw_if_index <id> enable | disable")                        \
22114 _(sw_interface_set_vxlan_bypass,                                        \
22115   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22116 _(sw_interface_set_geneve_bypass,                                       \
22117   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22118 _(sw_interface_set_l2_xconnect,                                         \
22119   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22120   "enable | disable")                                                   \
22121 _(sw_interface_set_l2_bridge,                                           \
22122   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22123   "[shg <split-horizon-group>] [bvi]\n"                                 \
22124   "enable | disable")                                                   \
22125 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22126 _(bridge_domain_add_del,                                                \
22127   "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") \
22128 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22129 _(l2fib_add_del,                                                        \
22130   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22131 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22132 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22133 _(l2_flags,                                                             \
22134   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22135 _(bridge_flags,                                                         \
22136   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22137 _(tap_create_v2,                                                        \
22138   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22139 _(tap_delete_v2,                                                        \
22140   "<vpp-if-name> | sw_if_index <id>")                                   \
22141 _(sw_interface_tap_v2_dump, "")                                         \
22142 _(virtio_pci_create,                                                    \
22143   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22144 _(virtio_pci_delete,                                                    \
22145   "<vpp-if-name> | sw_if_index <id>")                                   \
22146 _(sw_interface_virtio_pci_dump, "")                                     \
22147 _(bond_create,                                                          \
22148   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22149   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22150   "[id <if-id>]")                                                       \
22151 _(bond_delete,                                                          \
22152   "<vpp-if-name> | sw_if_index <id>")                                   \
22153 _(bond_enslave,                                                         \
22154   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22155 _(bond_detach_slave,                                                    \
22156   "sw_if_index <n>")                                                    \
22157 _(sw_interface_bond_dump, "")                                           \
22158 _(sw_interface_slave_dump,                                              \
22159   "<vpp-if-name> | sw_if_index <id>")                                   \
22160 _(ip_table_add_del,                                                     \
22161   "table <n> [ipv6] [add | del]\n")                                     \
22162 _(ip_add_del_route,                                                     \
22163   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22164   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22165   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22166   "[multipath] [count <n>] [del]")                                      \
22167 _(ip_mroute_add_del,                                                    \
22168   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22169   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22170 _(mpls_table_add_del,                                                   \
22171   "table <n> [add | del]\n")                                            \
22172 _(mpls_route_add_del,                                                   \
22173   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22174   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22175   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22176   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22177   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22178   "[count <n>] [del]")                                                  \
22179 _(mpls_ip_bind_unbind,                                                  \
22180   "<label> <addr/len>")                                                 \
22181 _(mpls_tunnel_add_del,                                                  \
22182   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22183   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22184   "[l2-only]  [out-label <n>]")                                         \
22185 _(sr_mpls_policy_add,                                                   \
22186   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22187 _(sr_mpls_policy_del,                                                   \
22188   "bsid <id>")                                                          \
22189 _(bier_table_add_del,                                                   \
22190   "<label> <sub-domain> <set> <bsl> [del]")                             \
22191 _(bier_route_add_del,                                                   \
22192   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22193   "[<intfc> | sw_if_index <id>]"                                        \
22194   "[weight <n>] [del] [multipath]")                                     \
22195 _(proxy_arp_add_del,                                                    \
22196   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22197 _(proxy_arp_intfc_enable_disable,                                       \
22198   "<intfc> | sw_if_index <id> enable | disable")                        \
22199 _(sw_interface_set_unnumbered,                                          \
22200   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22201 _(ip_neighbor_add_del,                                                  \
22202   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22203   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22204 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22205 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22206   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22207   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22208   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22209 _(reset_fib, "vrf <n> [ipv6]")                                          \
22210 _(dhcp_proxy_config,                                                    \
22211   "svr <v46-address> src <v46-address>\n"                               \
22212    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22213 _(dhcp_proxy_set_vss,                                                   \
22214   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22215 _(dhcp_proxy_dump, "ip6")                                               \
22216 _(dhcp_client_config,                                                   \
22217   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22218 _(set_ip_flow_hash,                                                     \
22219   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22220 _(sw_interface_ip6_enable_disable,                                      \
22221   "<intfc> | sw_if_index <id> enable | disable")                        \
22222 _(ip6nd_proxy_add_del,                                                  \
22223   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22224 _(ip6nd_proxy_dump, "")                                                 \
22225 _(sw_interface_ip6nd_ra_prefix,                                         \
22226   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22227   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22228   "[nolink] [isno]")                                                    \
22229 _(sw_interface_ip6nd_ra_config,                                         \
22230   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22231   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22232   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22233 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22234 _(l2_patch_add_del,                                                     \
22235   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22236   "enable | disable")                                                   \
22237 _(sr_localsid_add_del,                                                  \
22238   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22239   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22240 _(classify_add_del_table,                                               \
22241   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22242   " [del] [del-chain] mask <mask-value>\n"                              \
22243   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22244   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22245 _(classify_add_del_session,                                             \
22246   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22247   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22248   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22249   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22250 _(classify_set_interface_ip_table,                                      \
22251   "<intfc> | sw_if_index <nn> table <nn>")                              \
22252 _(classify_set_interface_l2_tables,                                     \
22253   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22254   "  [other-table <nn>]")                                               \
22255 _(get_node_index, "node <node-name")                                    \
22256 _(add_node_next, "node <node-name> next <next-node-name>")              \
22257 _(l2tpv3_create_tunnel,                                                 \
22258   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22259   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22260   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22261 _(l2tpv3_set_tunnel_cookies,                                            \
22262   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22263   "[new_remote_cookie <nn>]\n")                                         \
22264 _(l2tpv3_interface_enable_disable,                                      \
22265   "<intfc> | sw_if_index <nn> enable | disable")                        \
22266 _(l2tpv3_set_lookup_key,                                                \
22267   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22268 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22269 _(vxlan_offload_rx,                                                     \
22270   "hw { <interface name> | hw_if_index <nn>} "                          \
22271   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22272 _(vxlan_add_del_tunnel,                                                 \
22273   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22274   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22275   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22276 _(geneve_add_del_tunnel,                                                \
22277   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22278   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22279   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22280 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22281 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22282 _(gre_tunnel_add_del,                                                   \
22283   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22284   "[teb | erspan <session-id>] [del]")                                  \
22285 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22286 _(l2_fib_clear_table, "")                                               \
22287 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22288 _(l2_interface_vlan_tag_rewrite,                                        \
22289   "<intfc> | sw_if_index <nn> \n"                                       \
22290   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22291   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22292 _(create_vhost_user_if,                                                 \
22293         "socket <filename> [server] [renumber <dev_instance>] "         \
22294         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22295         "[mac <mac_address>]")                                          \
22296 _(modify_vhost_user_if,                                                 \
22297         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22298         "[server] [renumber <dev_instance>]")                           \
22299 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22300 _(sw_interface_vhost_user_dump, "")                                     \
22301 _(show_version, "")                                                     \
22302 _(show_threads, "")                                                     \
22303 _(vxlan_gpe_add_del_tunnel,                                             \
22304   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22305   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22306   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22307   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22308 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22309 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22310 _(interface_name_renumber,                                              \
22311   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22312 _(input_acl_set_interface,                                              \
22313   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22314   "  [l2-table <nn>] [del]")                                            \
22315 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22316 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22317   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22318 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22319 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22320 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22321 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22322 _(ip_dump, "ipv4 | ipv6")                                               \
22323 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22324 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22325   "  spid_id <n> ")                                                     \
22326 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22327   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22328   "  integ_alg <alg> integ_key <hex>")                                  \
22329 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22330   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22331   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22332   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22333 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22334   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22335   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22336   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22337   "  [instance <n>]")     \
22338 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22339 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22340 _(delete_loopback,"sw_if_index <nn>")                                   \
22341 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22342 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22343 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22344 _(want_interface_events,  "enable|disable")                             \
22345 _(get_first_msg_id, "client <name>")                                    \
22346 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22347 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22348   "fib-id <nn> [ip4][ip6][default]")                                    \
22349 _(get_node_graph, " ")                                                  \
22350 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22351 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22352 _(ioam_disable, "")                                                     \
22353 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22354                             " sw_if_index <sw_if_index> p <priority> "  \
22355                             "w <weight>] [del]")                        \
22356 _(one_add_del_locator, "locator-set <locator_name> "                    \
22357                         "iface <intf> | sw_if_index <sw_if_index> "     \
22358                         "p <priority> w <weight> [del]")                \
22359 _(one_add_del_local_eid,"vni <vni> eid "                                \
22360                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22361                          "locator-set <locator_name> [del]"             \
22362                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22363 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22364 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22365 _(one_enable_disable, "enable|disable")                                 \
22366 _(one_map_register_enable_disable, "enable|disable")                    \
22367 _(one_map_register_fallback_threshold, "<value>")                       \
22368 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22369 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22370                                "[seid <seid>] "                         \
22371                                "rloc <locator> p <prio> "               \
22372                                "w <weight> [rloc <loc> ... ] "          \
22373                                "action <action> [del-all]")             \
22374 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22375                           "<local-eid>")                                \
22376 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22377 _(one_use_petr, "ip-address> | disable")                                \
22378 _(one_map_request_mode, "src-dst|dst-only")                             \
22379 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22380 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22381 _(one_locator_set_dump, "[local | remote]")                             \
22382 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22383 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22384                        "[local] | [remote]")                            \
22385 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22386 _(one_ndp_bd_get, "")                                                   \
22387 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22388 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22389 _(one_l2_arp_bd_get, "")                                                \
22390 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22391 _(one_stats_enable_disable, "enable|disable")                           \
22392 _(show_one_stats_enable_disable, "")                                    \
22393 _(one_eid_table_vni_dump, "")                                           \
22394 _(one_eid_table_map_dump, "l2|l3")                                      \
22395 _(one_map_resolver_dump, "")                                            \
22396 _(one_map_server_dump, "")                                              \
22397 _(one_adjacencies_get, "vni <vni>")                                     \
22398 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22399 _(show_one_rloc_probe_state, "")                                        \
22400 _(show_one_map_register_state, "")                                      \
22401 _(show_one_status, "")                                                  \
22402 _(one_stats_dump, "")                                                   \
22403 _(one_stats_flush, "")                                                  \
22404 _(one_get_map_request_itr_rlocs, "")                                    \
22405 _(one_map_register_set_ttl, "<ttl>")                                    \
22406 _(one_set_transport_protocol, "udp|api")                                \
22407 _(one_get_transport_protocol, "")                                       \
22408 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22409 _(one_show_xtr_mode, "")                                                \
22410 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22411 _(one_show_pitr_mode, "")                                               \
22412 _(one_enable_disable_petr_mode, "enable|disable")                       \
22413 _(one_show_petr_mode, "")                                               \
22414 _(show_one_nsh_mapping, "")                                             \
22415 _(show_one_pitr, "")                                                    \
22416 _(show_one_use_petr, "")                                                \
22417 _(show_one_map_request_mode, "")                                        \
22418 _(show_one_map_register_ttl, "")                                        \
22419 _(show_one_map_register_fallback_threshold, "")                         \
22420 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22421                             " sw_if_index <sw_if_index> p <priority> "  \
22422                             "w <weight>] [del]")                        \
22423 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22424                         "iface <intf> | sw_if_index <sw_if_index> "     \
22425                         "p <priority> w <weight> [del]")                \
22426 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22427                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22428                          "locator-set <locator_name> [del]"             \
22429                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22430 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22431 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22432 _(lisp_enable_disable, "enable|disable")                                \
22433 _(lisp_map_register_enable_disable, "enable|disable")                   \
22434 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22435 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22436                                "[seid <seid>] "                         \
22437                                "rloc <locator> p <prio> "               \
22438                                "w <weight> [rloc <loc> ... ] "          \
22439                                "action <action> [del-all]")             \
22440 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22441                           "<local-eid>")                                \
22442 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22443 _(lisp_use_petr, "<ip-address> | disable")                              \
22444 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22445 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22446 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22447 _(lisp_locator_set_dump, "[local | remote]")                            \
22448 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22449 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22450                        "[local] | [remote]")                            \
22451 _(lisp_eid_table_vni_dump, "")                                          \
22452 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22453 _(lisp_map_resolver_dump, "")                                           \
22454 _(lisp_map_server_dump, "")                                             \
22455 _(lisp_adjacencies_get, "vni <vni>")                                    \
22456 _(gpe_fwd_entry_vnis_get, "")                                           \
22457 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22458 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22459                                 "[table <table-id>]")                   \
22460 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22461 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22462 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22463 _(gpe_get_encap_mode, "")                                               \
22464 _(lisp_gpe_add_del_iface, "up|down")                                    \
22465 _(lisp_gpe_enable_disable, "enable|disable")                            \
22466 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22467   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22468 _(show_lisp_rloc_probe_state, "")                                       \
22469 _(show_lisp_map_register_state, "")                                     \
22470 _(show_lisp_status, "")                                                 \
22471 _(lisp_get_map_request_itr_rlocs, "")                                   \
22472 _(show_lisp_pitr, "")                                                   \
22473 _(show_lisp_use_petr, "")                                               \
22474 _(show_lisp_map_request_mode, "")                                       \
22475 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22476 _(af_packet_delete, "name <host interface name>")                       \
22477 _(af_packet_dump, "")                                                   \
22478 _(policer_add_del, "name <policer name> <params> [del]")                \
22479 _(policer_dump, "[name <policer name>]")                                \
22480 _(policer_classify_set_interface,                                       \
22481   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22482   "  [l2-table <nn>] [del]")                                            \
22483 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22484 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22485     "[master|slave]")                                                   \
22486 _(netmap_delete, "name <interface name>")                               \
22487 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22488 _(mpls_fib_dump, "")                                                    \
22489 _(classify_table_ids, "")                                               \
22490 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22491 _(classify_table_info, "table_id <nn>")                                 \
22492 _(classify_session_dump, "table_id <nn>")                               \
22493 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22494     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22495     "[template_interval <nn>] [udp_checksum]")                          \
22496 _(ipfix_exporter_dump, "")                                              \
22497 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22498 _(ipfix_classify_stream_dump, "")                                       \
22499 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22500 _(ipfix_classify_table_dump, "")                                        \
22501 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22502 _(sw_interface_span_dump, "[l2]")                                           \
22503 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22504 _(pg_create_interface, "if_id <nn>")                                    \
22505 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22506 _(pg_enable_disable, "[stream <id>] disable")                           \
22507 _(ip_source_and_port_range_check_add_del,                               \
22508   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22509 _(ip_source_and_port_range_check_interface_add_del,                     \
22510   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22511   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22512 _(ipsec_gre_tunnel_add_del,                                             \
22513   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22514 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22515 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22516 _(l2_interface_pbb_tag_rewrite,                                         \
22517   "<intfc> | sw_if_index <nn> \n"                                       \
22518   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22519   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22520 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22521 _(flow_classify_set_interface,                                          \
22522   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22523 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22524 _(ip_fib_dump, "")                                                      \
22525 _(ip_mfib_dump, "")                                                     \
22526 _(ip6_fib_dump, "")                                                     \
22527 _(ip6_mfib_dump, "")                                                    \
22528 _(feature_enable_disable, "arc_name <arc_name> "                        \
22529   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22530 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22531 "[disable]")                                                            \
22532 _(l2_xconnect_dump, "")                                                 \
22533 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22534 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22535 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22536 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22537 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22538 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22539 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22540   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22541 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22542 _(sock_init_shm, "size <nnn>")                                          \
22543 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22544 _(dns_enable_disable, "[enable][disable]")                              \
22545 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22546 _(dns_resolve_name, "<hostname>")                                       \
22547 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22548 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22549 _(dns_resolve_name, "<hostname>")                                       \
22550 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22551   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22552 _(session_rules_dump, "")                                               \
22553 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22554 _(output_acl_set_interface,                                             \
22555   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22556   "  [l2-table <nn>] [del]")                                            \
22557 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22558
22559 /* List of command functions, CLI names map directly to functions */
22560 #define foreach_cli_function                                    \
22561 _(comment, "usage: comment <ignore-rest-of-line>")              \
22562 _(dump_interface_table, "usage: dump_interface_table")          \
22563 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22564 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22565 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22566 _(dump_macro_table, "usage: dump_macro_table ")                 \
22567 _(dump_node_table, "usage: dump_node_table")                    \
22568 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22569 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22570 _(echo, "usage: echo <message>")                                \
22571 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22572 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22573 _(help, "usage: help")                                          \
22574 _(q, "usage: quit")                                             \
22575 _(quit, "usage: quit")                                          \
22576 _(search_node_table, "usage: search_node_table <name>...")      \
22577 _(set, "usage: set <variable-name> <value>")                    \
22578 _(script, "usage: script <file-name>")                          \
22579 _(statseg, "usage: statseg");                                   \
22580 _(unset, "usage: unset <variable-name>")
22581
22582 #define _(N,n)                                  \
22583     static void vl_api_##n##_t_handler_uni      \
22584     (vl_api_##n##_t * mp)                       \
22585     {                                           \
22586         vat_main_t * vam = &vat_main;           \
22587         if (vam->json_output) {                 \
22588             vl_api_##n##_t_handler_json(mp);    \
22589         } else {                                \
22590             vl_api_##n##_t_handler(mp);         \
22591         }                                       \
22592     }
22593 foreach_vpe_api_reply_msg;
22594 #if VPP_API_TEST_BUILTIN == 0
22595 foreach_standalone_reply_msg;
22596 #endif
22597 #undef _
22598
22599 void
22600 vat_api_hookup (vat_main_t * vam)
22601 {
22602 #define _(N,n)                                                  \
22603     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22604                            vl_api_##n##_t_handler_uni,          \
22605                            vl_noop_handler,                     \
22606                            vl_api_##n##_t_endian,               \
22607                            vl_api_##n##_t_print,                \
22608                            sizeof(vl_api_##n##_t), 1);
22609   foreach_vpe_api_reply_msg;
22610 #if VPP_API_TEST_BUILTIN == 0
22611   foreach_standalone_reply_msg;
22612 #endif
22613 #undef _
22614
22615 #if (VPP_API_TEST_BUILTIN==0)
22616   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22617
22618   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22619
22620   vam->function_by_name = hash_create_string (0, sizeof (uword));
22621
22622   vam->help_by_name = hash_create_string (0, sizeof (uword));
22623 #endif
22624
22625   /* API messages we can send */
22626 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22627   foreach_vpe_api_msg;
22628 #undef _
22629
22630   /* Help strings */
22631 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22632   foreach_vpe_api_msg;
22633 #undef _
22634
22635   /* CLI functions */
22636 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22637   foreach_cli_function;
22638 #undef _
22639
22640   /* Help strings */
22641 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22642   foreach_cli_function;
22643 #undef _
22644 }
22645
22646 #if VPP_API_TEST_BUILTIN
22647 static clib_error_t *
22648 vat_api_hookup_shim (vlib_main_t * vm)
22649 {
22650   vat_api_hookup (&vat_main);
22651   return 0;
22652 }
22653
22654 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22655 #endif
22656
22657 /*
22658  * fd.io coding-style-patch-verification: ON
22659  *
22660  * Local Variables:
22661  * eval: (c-set-style "gnu")
22662  * End:
22663  */