api: refactor format_vl_api_prefix_t return keys
[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 (vl_api_ip4_address_t * i)
713 {
714   ip4_address_t *a = (ip4_address_t *) i;
715   u32 v;
716
717   v = ntohl (a->as_u32) + 1;
718   a->as_u32 = ntohl (v);
719 }
720
721 static void
722 increment_v6_address (vl_api_ip6_address_t * i)
723 {
724   ip6_address_t *a = (ip6_address_t *) i;
725   u64 v0, v1;
726
727   v0 = clib_net_to_host_u64 (a->as_u64[0]);
728   v1 = clib_net_to_host_u64 (a->as_u64[1]);
729
730   v1 += 1;
731   if (v1 == 0)
732     v0 += 1;
733   a->as_u64[0] = clib_net_to_host_u64 (v0);
734   a->as_u64[1] = clib_net_to_host_u64 (v1);
735 }
736
737 static void
738 increment_address (vl_api_address_t * a)
739 {
740   if (a->af == ADDRESS_IP4)
741     increment_v4_address (&a->un.ip4);
742   else if (a->af == ADDRESS_IP6)
743     increment_v6_address (&a->un.ip6);
744 }
745
746 static void
747 set_ip4_address (vl_api_address_t * a, u32 v)
748 {
749   if (a->af == ADDRESS_IP4)
750     {
751       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
752       i->as_u32 = v;
753     }
754 }
755
756 static void
757 increment_mac_address (u8 * mac)
758 {
759   u64 tmp = *((u64 *) mac);
760   tmp = clib_net_to_host_u64 (tmp);
761   tmp += 1 << 16;               /* skip unused (least significant) octets */
762   tmp = clib_host_to_net_u64 (tmp);
763
764   clib_memcpy (mac, &tmp, 6);
765 }
766
767 static void
768 vat_json_object_add_address (vat_json_node_t * node,
769                              const char *str, const vl_api_address_t * addr)
770 {
771   if (ADDRESS_IP6 == addr->af)
772     {
773       struct in6_addr ip6;
774
775       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
776       vat_json_object_add_ip6 (node, str, ip6);
777     }
778   else
779     {
780       struct in_addr ip4;
781
782       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
783       vat_json_object_add_ip4 (node, str, ip4);
784     }
785 }
786
787 static void
788 vat_json_object_add_prefix (vat_json_node_t * node,
789                             const vl_api_prefix_t * prefix)
790 {
791   vat_json_object_add_uint (node, "len", prefix->len);
792   vat_json_object_add_address (node, "address", &prefix->address);
793 }
794
795 static void vl_api_create_loopback_reply_t_handler
796   (vl_api_create_loopback_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_create_loopback_reply_t_handler_json
808   (vl_api_create_loopback_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819   vam->retval = ntohl (mp->retval);
820   vam->result_ready = 1;
821 }
822
823 static void vl_api_create_loopback_instance_reply_t_handler
824   (vl_api_create_loopback_instance_reply_t * mp)
825 {
826   vat_main_t *vam = &vat_main;
827   i32 retval = ntohl (mp->retval);
828
829   vam->retval = retval;
830   vam->regenerate_interface_table = 1;
831   vam->sw_if_index = ntohl (mp->sw_if_index);
832   vam->result_ready = 1;
833 }
834
835 static void vl_api_create_loopback_instance_reply_t_handler_json
836   (vl_api_create_loopback_instance_reply_t * mp)
837 {
838   vat_main_t *vam = &vat_main;
839   vat_json_node_t node;
840
841   vat_json_init_object (&node);
842   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
843   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
844
845   vat_json_print (vam->ofp, &node);
846   vat_json_free (&node);
847   vam->retval = ntohl (mp->retval);
848   vam->result_ready = 1;
849 }
850
851 static void vl_api_af_packet_create_reply_t_handler
852   (vl_api_af_packet_create_reply_t * mp)
853 {
854   vat_main_t *vam = &vat_main;
855   i32 retval = ntohl (mp->retval);
856
857   vam->retval = retval;
858   vam->regenerate_interface_table = 1;
859   vam->sw_if_index = ntohl (mp->sw_if_index);
860   vam->result_ready = 1;
861 }
862
863 static void vl_api_af_packet_create_reply_t_handler_json
864   (vl_api_af_packet_create_reply_t * mp)
865 {
866   vat_main_t *vam = &vat_main;
867   vat_json_node_t node;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
872
873   vat_json_print (vam->ofp, &node);
874   vat_json_free (&node);
875
876   vam->retval = ntohl (mp->retval);
877   vam->result_ready = 1;
878 }
879
880 static void vl_api_create_vlan_subif_reply_t_handler
881   (vl_api_create_vlan_subif_reply_t * mp)
882 {
883   vat_main_t *vam = &vat_main;
884   i32 retval = ntohl (mp->retval);
885
886   vam->retval = retval;
887   vam->regenerate_interface_table = 1;
888   vam->sw_if_index = ntohl (mp->sw_if_index);
889   vam->result_ready = 1;
890 }
891
892 static void vl_api_create_vlan_subif_reply_t_handler_json
893   (vl_api_create_vlan_subif_reply_t * mp)
894 {
895   vat_main_t *vam = &vat_main;
896   vat_json_node_t node;
897
898   vat_json_init_object (&node);
899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 static void vl_api_create_subif_reply_t_handler
910   (vl_api_create_subif_reply_t * mp)
911 {
912   vat_main_t *vam = &vat_main;
913   i32 retval = ntohl (mp->retval);
914
915   vam->retval = retval;
916   vam->regenerate_interface_table = 1;
917   vam->sw_if_index = ntohl (mp->sw_if_index);
918   vam->result_ready = 1;
919 }
920
921 static void vl_api_create_subif_reply_t_handler_json
922   (vl_api_create_subif_reply_t * mp)
923 {
924   vat_main_t *vam = &vat_main;
925   vat_json_node_t node;
926
927   vat_json_init_object (&node);
928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
929   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
930
931   vat_json_print (vam->ofp, &node);
932   vat_json_free (&node);
933
934   vam->retval = ntohl (mp->retval);
935   vam->result_ready = 1;
936 }
937
938 static void vl_api_interface_name_renumber_reply_t_handler
939   (vl_api_interface_name_renumber_reply_t * mp)
940 {
941   vat_main_t *vam = &vat_main;
942   i32 retval = ntohl (mp->retval);
943
944   vam->retval = retval;
945   vam->regenerate_interface_table = 1;
946   vam->result_ready = 1;
947 }
948
949 static void vl_api_interface_name_renumber_reply_t_handler_json
950   (vl_api_interface_name_renumber_reply_t * mp)
951 {
952   vat_main_t *vam = &vat_main;
953   vat_json_node_t node;
954
955   vat_json_init_object (&node);
956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
957
958   vat_json_print (vam->ofp, &node);
959   vat_json_free (&node);
960
961   vam->retval = ntohl (mp->retval);
962   vam->result_ready = 1;
963 }
964
965 /*
966  * Special-case: build the interface table, maintain
967  * the next loopback sw_if_index vbl.
968  */
969 static void vl_api_sw_interface_details_t_handler
970   (vl_api_sw_interface_details_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   u8 *s = format (0, "%s%c", mp->interface_name, 0);
974
975   hash_set_mem (vam->sw_if_index_by_interface_name, s,
976                 ntohl (mp->sw_if_index));
977
978   /* In sub interface case, fill the sub interface table entry */
979   if (mp->sw_if_index != mp->sup_sw_if_index)
980     {
981       sw_interface_subif_t *sub = NULL;
982
983       vec_add2 (vam->sw_if_subif_table, sub, 1);
984
985       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
986       strncpy ((char *) sub->interface_name, (char *) s,
987                vec_len (sub->interface_name));
988       sub->sw_if_index = ntohl (mp->sw_if_index);
989       sub->sub_id = ntohl (mp->sub_id);
990
991       sub->sub_dot1ad = mp->sub_dot1ad;
992       sub->sub_number_of_tags = mp->sub_number_of_tags;
993       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
994       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
995       sub->sub_exact_match = mp->sub_exact_match;
996       sub->sub_default = mp->sub_default;
997       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
998       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
999
1000       /* vlan tag rewrite */
1001       sub->vtr_op = ntohl (mp->vtr_op);
1002       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1003       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1004       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1005     }
1006 }
1007
1008 static void vl_api_sw_interface_details_t_handler_json
1009   (vl_api_sw_interface_details_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   vat_json_node_t *node = NULL;
1013
1014   if (VAT_JSON_ARRAY != vam->json_tree.type)
1015     {
1016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1017       vat_json_init_array (&vam->json_tree);
1018     }
1019   node = vat_json_array_add (&vam->json_tree);
1020
1021   vat_json_init_object (node);
1022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1023   vat_json_object_add_uint (node, "sup_sw_if_index",
1024                             ntohl (mp->sup_sw_if_index));
1025   vat_json_object_add_uint (node, "l2_address_length",
1026                             ntohl (mp->l2_address_length));
1027   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1028                              sizeof (mp->l2_address));
1029   vat_json_object_add_string_copy (node, "interface_name",
1030                                    mp->interface_name);
1031   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1032   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1033   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1034   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1035   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1036   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1037   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1038   vat_json_object_add_uint (node, "sub_number_of_tags",
1039                             mp->sub_number_of_tags);
1040   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1041                             ntohs (mp->sub_outer_vlan_id));
1042   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1043                             ntohs (mp->sub_inner_vlan_id));
1044   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1045   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1046   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1047                             mp->sub_outer_vlan_id_any);
1048   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1049                             mp->sub_inner_vlan_id_any);
1050   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1051   vat_json_object_add_uint (node, "vtr_push_dot1q",
1052                             ntohl (mp->vtr_push_dot1q));
1053   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1054   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1055   if (mp->sub_dot1ah)
1056     {
1057       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_dmac));
1061       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1062                                        format (0, "%U",
1063                                                format_ethernet_address,
1064                                                &mp->b_smac));
1065       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1066       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1067     }
1068 }
1069
1070 #if VPP_API_TEST_BUILTIN == 0
1071 static void vl_api_sw_interface_event_t_handler
1072   (vl_api_sw_interface_event_t * mp)
1073 {
1074   vat_main_t *vam = &vat_main;
1075   if (vam->interface_event_display)
1076     errmsg ("interface flags: sw_if_index %d %s %s",
1077             ntohl (mp->sw_if_index),
1078             mp->admin_up_down ? "admin-up" : "admin-down",
1079             mp->link_up_down ? "link-up" : "link-down");
1080 }
1081 #endif
1082
1083 __clib_unused static void
1084 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1085 {
1086   /* JSON output not supported */
1087 }
1088
1089 static void
1090 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   i32 retval = ntohl (mp->retval);
1094
1095   vam->retval = retval;
1096   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1097   vam->result_ready = 1;
1098 }
1099
1100 static void
1101 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105   api_main_t *am = &api_main;
1106   void *oldheap;
1107   u8 *reply;
1108
1109   vat_json_init_object (&node);
1110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1111   vat_json_object_add_uint (&node, "reply_in_shmem",
1112                             ntohl (mp->reply_in_shmem));
1113   /* Toss the shared-memory original... */
1114   pthread_mutex_lock (&am->vlib_rp->mutex);
1115   oldheap = svm_push_data_heap (am->vlib_rp);
1116
1117   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1118   vec_free (reply);
1119
1120   svm_pop_heap (oldheap);
1121   pthread_mutex_unlock (&am->vlib_rp->mutex);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void
1131 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   u32 length = vl_api_string_len (&mp->reply);
1136
1137   vec_reset_length (vam->cmd_reply);
1138
1139   vam->retval = retval;
1140   if (retval == 0)
1141     {
1142       vec_validate (vam->cmd_reply, length);
1143       clib_memcpy ((char *) (vam->cmd_reply),
1144                    vl_api_from_api_string (&mp->reply), length);
1145       vam->cmd_reply[length] = 0;
1146     }
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   vat_json_node_t node;
1155
1156   vec_reset_length (vam->cmd_reply);
1157
1158   vat_json_init_object (&node);
1159   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1160   vat_json_object_add_string_copy (&node, "reply",
1161                                    vl_api_from_api_string (&mp->reply));
1162
1163   vat_json_print (vam->ofp, &node);
1164   vat_json_free (&node);
1165
1166   vam->retval = ntohl (mp->retval);
1167   vam->result_ready = 1;
1168 }
1169
1170 static void vl_api_classify_add_del_table_reply_t_handler
1171   (vl_api_classify_add_del_table_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   i32 retval = ntohl (mp->retval);
1175   if (vam->async_mode)
1176     {
1177       vam->async_errors += (retval < 0);
1178     }
1179   else
1180     {
1181       vam->retval = retval;
1182       if (retval == 0 &&
1183           ((mp->new_table_index != 0xFFFFFFFF) ||
1184            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1185            (mp->match_n_vectors != 0xFFFFFFFF)))
1186         /*
1187          * Note: this is just barely thread-safe, depends on
1188          * the main thread spinning waiting for an answer...
1189          */
1190         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1191                 ntohl (mp->new_table_index),
1192                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_classify_add_del_table_reply_t_handler_json
1198   (vl_api_classify_add_del_table_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "new_table_index",
1206                             ntohl (mp->new_table_index));
1207   vat_json_object_add_uint (&node, "skip_n_vectors",
1208                             ntohl (mp->skip_n_vectors));
1209   vat_json_object_add_uint (&node, "match_n_vectors",
1210                             ntohl (mp->match_n_vectors));
1211
1212   vat_json_print (vam->ofp, &node);
1213   vat_json_free (&node);
1214
1215   vam->retval = ntohl (mp->retval);
1216   vam->result_ready = 1;
1217 }
1218
1219 static void vl_api_get_node_index_reply_t_handler
1220   (vl_api_get_node_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   i32 retval = ntohl (mp->retval);
1224   if (vam->async_mode)
1225     {
1226       vam->async_errors += (retval < 0);
1227     }
1228   else
1229     {
1230       vam->retval = retval;
1231       if (retval == 0)
1232         errmsg ("node index %d", ntohl (mp->node_index));
1233       vam->result_ready = 1;
1234     }
1235 }
1236
1237 static void vl_api_get_node_index_reply_t_handler_json
1238   (vl_api_get_node_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   vat_json_node_t node;
1242
1243   vat_json_init_object (&node);
1244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1245   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void vl_api_get_next_index_reply_t_handler
1255   (vl_api_get_next_index_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   i32 retval = ntohl (mp->retval);
1259   if (vam->async_mode)
1260     {
1261       vam->async_errors += (retval < 0);
1262     }
1263   else
1264     {
1265       vam->retval = retval;
1266       if (retval == 0)
1267         errmsg ("next node index %d", ntohl (mp->next_index));
1268       vam->result_ready = 1;
1269     }
1270 }
1271
1272 static void vl_api_get_next_index_reply_t_handler_json
1273   (vl_api_get_next_index_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   vat_json_node_t node;
1277
1278   vat_json_init_object (&node);
1279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1280   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1281
1282   vat_json_print (vam->ofp, &node);
1283   vat_json_free (&node);
1284
1285   vam->retval = ntohl (mp->retval);
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_add_node_next_reply_t_handler
1290   (vl_api_add_node_next_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294   if (vam->async_mode)
1295     {
1296       vam->async_errors += (retval < 0);
1297     }
1298   else
1299     {
1300       vam->retval = retval;
1301       if (retval == 0)
1302         errmsg ("next index %d", ntohl (mp->next_index));
1303       vam->result_ready = 1;
1304     }
1305 }
1306
1307 static void vl_api_add_node_next_reply_t_handler_json
1308   (vl_api_add_node_next_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t node;
1312
1313   vat_json_init_object (&node);
1314   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1315   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1316
1317   vat_json_print (vam->ofp, &node);
1318   vat_json_free (&node);
1319
1320   vam->retval = ntohl (mp->retval);
1321   vam->result_ready = 1;
1322 }
1323
1324 static void vl_api_show_version_reply_t_handler
1325   (vl_api_show_version_reply_t * mp)
1326 {
1327   vat_main_t *vam = &vat_main;
1328   i32 retval = ntohl (mp->retval);
1329
1330   if (retval >= 0)
1331     {
1332       u8 *s = 0;
1333       char *p = (char *) &mp->program;
1334
1335       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1336       errmsg ("        program: %v\n", s);
1337       vec_free (s);
1338
1339       p +=
1340         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1341       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1342       errmsg ("        version: %v\n", s);
1343       vec_free (s);
1344
1345       p +=
1346         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1347       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1348       errmsg ("     build date: %v\n", s);
1349       vec_free (s);
1350
1351       p +=
1352         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1353       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1354       errmsg ("build directory: %v\n", s);
1355       vec_free (s);
1356     }
1357   vam->retval = retval;
1358   vam->result_ready = 1;
1359 }
1360
1361 static void vl_api_show_version_reply_t_handler_json
1362   (vl_api_show_version_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369   char *p = (char *) &mp->program;
1370   vat_json_object_add_string_copy (&node, "program",
1371                                    vl_api_from_api_string ((vl_api_string_t *)
1372                                                            p));
1373   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1374   vat_json_object_add_string_copy (&node, "version",
1375                                    vl_api_from_api_string ((vl_api_string_t *)
1376                                                            p));
1377   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1378   vat_json_object_add_string_copy (&node, "build_date",
1379                                    vl_api_from_api_string ((vl_api_string_t *)
1380                                                            p));
1381   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1382   vat_json_object_add_string_copy (&node, "build_directory",
1383                                    vl_api_from_api_string ((vl_api_string_t *)
1384                                                            p));
1385
1386   vat_json_print (vam->ofp, &node);
1387   vat_json_free (&node);
1388
1389   vam->retval = ntohl (mp->retval);
1390   vam->result_ready = 1;
1391 }
1392
1393 static void vl_api_show_threads_reply_t_handler
1394   (vl_api_show_threads_reply_t * mp)
1395 {
1396   vat_main_t *vam = &vat_main;
1397   i32 retval = ntohl (mp->retval);
1398   int i, count = 0;
1399
1400   if (retval >= 0)
1401     count = ntohl (mp->count);
1402
1403   for (i = 0; i < count; i++)
1404     print (vam->ofp,
1405            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1406            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1407            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1408            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1409            ntohl (mp->thread_data[i].cpu_socket));
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static void vl_api_show_threads_reply_t_handler_json
1416   (vl_api_show_threads_reply_t * mp)
1417 {
1418   vat_main_t *vam = &vat_main;
1419   vat_json_node_t node;
1420   vl_api_thread_data_t *td;
1421   i32 retval = ntohl (mp->retval);
1422   int i, count = 0;
1423
1424   if (retval >= 0)
1425     count = ntohl (mp->count);
1426
1427   vat_json_init_object (&node);
1428   vat_json_object_add_int (&node, "retval", retval);
1429   vat_json_object_add_uint (&node, "count", count);
1430
1431   for (i = 0; i < count; i++)
1432     {
1433       td = &mp->thread_data[i];
1434       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1435       vat_json_object_add_string_copy (&node, "name", td->name);
1436       vat_json_object_add_string_copy (&node, "type", td->type);
1437       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1438       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1439       vat_json_object_add_int (&node, "core", ntohl (td->id));
1440       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1441     }
1442
1443   vat_json_print (vam->ofp, &node);
1444   vat_json_free (&node);
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static int
1451 api_show_threads (vat_main_t * vam)
1452 {
1453   vl_api_show_threads_t *mp;
1454   int ret;
1455
1456   print (vam->ofp,
1457          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1458          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1459
1460   M (SHOW_THREADS, mp);
1461
1462   S (mp);
1463   W (ret);
1464   return ret;
1465 }
1466
1467 static void
1468 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1469 {
1470   u32 sw_if_index = ntohl (mp->sw_if_index);
1471   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1472           mp->mac_ip ? "mac/ip binding" : "address resolution",
1473           ntohl (mp->pid), format_ip4_address, mp->ip,
1474           format_vl_api_mac_address, &mp->mac, sw_if_index);
1475 }
1476
1477 static void
1478 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1479 {
1480   /* JSON output not supported */
1481 }
1482
1483 static void
1484 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1485 {
1486   u32 sw_if_index = ntohl (mp->sw_if_index);
1487   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1488           mp->mac_ip ? "mac/ip binding" : "address resolution",
1489           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1490           format_vl_api_mac_address, mp->mac, sw_if_index);
1491 }
1492
1493 static void
1494 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1495 {
1496   /* JSON output not supported */
1497 }
1498
1499 static void
1500 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1501 {
1502   u32 n_macs = ntohl (mp->n_macs);
1503   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1504           ntohl (mp->pid), mp->client_index, n_macs);
1505   int i;
1506   for (i = 0; i < n_macs; i++)
1507     {
1508       vl_api_mac_entry_t *mac = &mp->mac[i];
1509       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1510               i + 1, ntohl (mac->sw_if_index),
1511               format_ethernet_address, mac->mac_addr, mac->action);
1512       if (i == 1000)
1513         break;
1514     }
1515 }
1516
1517 static void
1518 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1519 {
1520   /* JSON output not supported */
1521 }
1522
1523 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1524 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1525
1526 /*
1527  * Special-case: build the bridge domain table, maintain
1528  * the next bd id vbl.
1529  */
1530 static void vl_api_bridge_domain_details_t_handler
1531   (vl_api_bridge_domain_details_t * mp)
1532 {
1533   vat_main_t *vam = &vat_main;
1534   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1535   int i;
1536
1537   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1538          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1539
1540   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1541          ntohl (mp->bd_id), mp->learn, mp->forward,
1542          mp->flood, ntohl (mp->bvi_sw_if_index),
1543          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1544
1545   if (n_sw_ifs)
1546     {
1547       vl_api_bridge_domain_sw_if_t *sw_ifs;
1548       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1549              "Interface Name");
1550
1551       sw_ifs = mp->sw_if_details;
1552       for (i = 0; i < n_sw_ifs; i++)
1553         {
1554           u8 *sw_if_name = 0;
1555           u32 sw_if_index;
1556           hash_pair_t *p;
1557
1558           sw_if_index = ntohl (sw_ifs->sw_if_index);
1559
1560           /* *INDENT-OFF* */
1561           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1562                              ({
1563                                if ((u32) p->value[0] == sw_if_index)
1564                                  {
1565                                    sw_if_name = (u8 *)(p->key);
1566                                    break;
1567                                  }
1568                              }));
1569           /* *INDENT-ON* */
1570           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1571                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1572                  "sw_if_index not found!");
1573
1574           sw_ifs++;
1575         }
1576     }
1577 }
1578
1579 static void vl_api_bridge_domain_details_t_handler_json
1580   (vl_api_bridge_domain_details_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   vat_json_node_t *node, *array = NULL;
1584   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1585
1586   if (VAT_JSON_ARRAY != vam->json_tree.type)
1587     {
1588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1589       vat_json_init_array (&vam->json_tree);
1590     }
1591   node = vat_json_array_add (&vam->json_tree);
1592
1593   vat_json_init_object (node);
1594   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1595   vat_json_object_add_uint (node, "flood", mp->flood);
1596   vat_json_object_add_uint (node, "forward", mp->forward);
1597   vat_json_object_add_uint (node, "learn", mp->learn);
1598   vat_json_object_add_uint (node, "bvi_sw_if_index",
1599                             ntohl (mp->bvi_sw_if_index));
1600   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1601   array = vat_json_object_add (node, "sw_if");
1602   vat_json_init_array (array);
1603
1604
1605
1606   if (n_sw_ifs)
1607     {
1608       vl_api_bridge_domain_sw_if_t *sw_ifs;
1609       int i;
1610
1611       sw_ifs = mp->sw_if_details;
1612       for (i = 0; i < n_sw_ifs; i++)
1613         {
1614           node = vat_json_array_add (array);
1615           vat_json_init_object (node);
1616           vat_json_object_add_uint (node, "sw_if_index",
1617                                     ntohl (sw_ifs->sw_if_index));
1618           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1619           sw_ifs++;
1620         }
1621     }
1622 }
1623
1624 static void vl_api_control_ping_reply_t_handler
1625   (vl_api_control_ping_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->result_ready = 1;
1637     }
1638   if (vam->socket_client_main)
1639     vam->socket_client_main->control_pings_outstanding--;
1640 }
1641
1642 static void vl_api_control_ping_reply_t_handler_json
1643   (vl_api_control_ping_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647
1648   if (VAT_JSON_NONE != vam->json_tree.type)
1649     {
1650       vat_json_print (vam->ofp, &vam->json_tree);
1651       vat_json_free (&vam->json_tree);
1652       vam->json_tree.type = VAT_JSON_NONE;
1653     }
1654   else
1655     {
1656       /* just print [] */
1657       vat_json_init_array (&vam->json_tree);
1658       vat_json_print (vam->ofp, &vam->json_tree);
1659       vam->json_tree.type = VAT_JSON_NONE;
1660     }
1661
1662   vam->retval = retval;
1663   vam->result_ready = 1;
1664 }
1665
1666 static void
1667   vl_api_bridge_domain_set_mac_age_reply_t_handler
1668   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1669 {
1670   vat_main_t *vam = &vat_main;
1671   i32 retval = ntohl (mp->retval);
1672   if (vam->async_mode)
1673     {
1674       vam->async_errors += (retval < 0);
1675     }
1676   else
1677     {
1678       vam->retval = retval;
1679       vam->result_ready = 1;
1680     }
1681 }
1682
1683 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1684   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1685 {
1686   vat_main_t *vam = &vat_main;
1687   vat_json_node_t node;
1688
1689   vat_json_init_object (&node);
1690   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void
1700 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_l2_flags_reply_t_handler_json
1716   (vl_api_l2_flags_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1724                             ntohl (mp->resulting_feature_bitmap));
1725
1726   vat_json_print (vam->ofp, &node);
1727   vat_json_free (&node);
1728
1729   vam->retval = ntohl (mp->retval);
1730   vam->result_ready = 1;
1731 }
1732
1733 static void vl_api_bridge_flags_reply_t_handler
1734   (vl_api_bridge_flags_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_bridge_flags_reply_t_handler_json
1750   (vl_api_bridge_flags_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1758                             ntohl (mp->resulting_feature_bitmap));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void
1768 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1769 {
1770   vat_main_t *vam = &vat_main;
1771   i32 retval = ntohl (mp->retval);
1772   if (vam->async_mode)
1773     {
1774       vam->async_errors += (retval < 0);
1775     }
1776   else
1777     {
1778       vam->retval = retval;
1779       vam->sw_if_index = ntohl (mp->sw_if_index);
1780       vam->result_ready = 1;
1781     }
1782
1783 }
1784
1785 static void vl_api_tap_create_v2_reply_t_handler_json
1786   (vl_api_tap_create_v2_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800
1801 }
1802
1803 static void
1804 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1805 {
1806   vat_main_t *vam = &vat_main;
1807   i32 retval = ntohl (mp->retval);
1808   if (vam->async_mode)
1809     {
1810       vam->async_errors += (retval < 0);
1811     }
1812   else
1813     {
1814       vam->retval = retval;
1815       vam->result_ready = 1;
1816     }
1817 }
1818
1819 static void vl_api_tap_delete_v2_reply_t_handler_json
1820   (vl_api_tap_delete_v2_reply_t * mp)
1821 {
1822   vat_main_t *vam = &vat_main;
1823   vat_json_node_t node;
1824
1825   vat_json_init_object (&node);
1826   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833 }
1834
1835 static void
1836 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1837                                           mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841   if (vam->async_mode)
1842     {
1843       vam->async_errors += (retval < 0);
1844     }
1845   else
1846     {
1847       vam->retval = retval;
1848       vam->sw_if_index = ntohl (mp->sw_if_index);
1849       vam->result_ready = 1;
1850     }
1851 }
1852
1853 static void vl_api_virtio_pci_create_reply_t_handler_json
1854   (vl_api_virtio_pci_create_reply_t * mp)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   vat_json_node_t node;
1858
1859   vat_json_init_object (&node);
1860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1861   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1862
1863   vat_json_print (vam->ofp, &node);
1864   vat_json_free (&node);
1865
1866   vam->retval = ntohl (mp->retval);
1867   vam->result_ready = 1;
1868
1869 }
1870
1871 static void
1872 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1873                                           mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   i32 retval = ntohl (mp->retval);
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_virtio_pci_delete_reply_t_handler_json
1889   (vl_api_virtio_pci_delete_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->sw_if_index = ntohl (mp->sw_if_index);
1918       vam->result_ready = 1;
1919     }
1920 }
1921
1922 static void vl_api_bond_create_reply_t_handler_json
1923   (vl_api_bond_create_reply_t * mp)
1924 {
1925   vat_main_t *vam = &vat_main;
1926   vat_json_node_t node;
1927
1928   vat_json_init_object (&node);
1929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1930   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1931
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void
1940 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944
1945   if (vam->async_mode)
1946     {
1947       vam->async_errors += (retval < 0);
1948     }
1949   else
1950     {
1951       vam->retval = retval;
1952       vam->result_ready = 1;
1953     }
1954 }
1955
1956 static void vl_api_bond_delete_reply_t_handler_json
1957   (vl_api_bond_delete_reply_t * mp)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   vat_json_node_t node;
1961
1962   vat_json_init_object (&node);
1963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void
1973 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   i32 retval = ntohl (mp->retval);
1977
1978   if (vam->async_mode)
1979     {
1980       vam->async_errors += (retval < 0);
1981     }
1982   else
1983     {
1984       vam->retval = retval;
1985       vam->result_ready = 1;
1986     }
1987 }
1988
1989 static void vl_api_bond_enslave_reply_t_handler_json
1990   (vl_api_bond_enslave_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997
1998   vat_json_print (vam->ofp, &node);
1999   vat_json_free (&node);
2000
2001   vam->retval = ntohl (mp->retval);
2002   vam->result_ready = 1;
2003 }
2004
2005 static void
2006 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2007                                           mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   i32 retval = ntohl (mp->retval);
2011
2012   if (vam->async_mode)
2013     {
2014       vam->async_errors += (retval < 0);
2015     }
2016   else
2017     {
2018       vam->retval = retval;
2019       vam->result_ready = 1;
2020     }
2021 }
2022
2023 static void vl_api_bond_detach_slave_reply_t_handler_json
2024   (vl_api_bond_detach_slave_reply_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t node;
2028
2029   vat_json_init_object (&node);
2030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2031
2032   vat_json_print (vam->ofp, &node);
2033   vat_json_free (&node);
2034
2035   vam->retval = ntohl (mp->retval);
2036   vam->result_ready = 1;
2037 }
2038
2039 static void vl_api_sw_interface_bond_details_t_handler
2040   (vl_api_sw_interface_bond_details_t * mp)
2041 {
2042   vat_main_t *vam = &vat_main;
2043
2044   print (vam->ofp,
2045          "%-16s %-12d %-12U %-13U %-14u %-14u",
2046          mp->interface_name, ntohl (mp->sw_if_index),
2047          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2048          ntohl (mp->active_slaves), ntohl (mp->slaves));
2049 }
2050
2051 static void vl_api_sw_interface_bond_details_t_handler_json
2052   (vl_api_sw_interface_bond_details_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   vat_json_node_t *node = NULL;
2056
2057   if (VAT_JSON_ARRAY != vam->json_tree.type)
2058     {
2059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2060       vat_json_init_array (&vam->json_tree);
2061     }
2062   node = vat_json_array_add (&vam->json_tree);
2063
2064   vat_json_init_object (node);
2065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2066   vat_json_object_add_string_copy (node, "interface_name",
2067                                    mp->interface_name);
2068   vat_json_object_add_uint (node, "mode", mp->mode);
2069   vat_json_object_add_uint (node, "load_balance", mp->lb);
2070   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2071   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2072 }
2073
2074 static int
2075 api_sw_interface_bond_dump (vat_main_t * vam)
2076 {
2077   vl_api_sw_interface_bond_dump_t *mp;
2078   vl_api_control_ping_t *mp_ping;
2079   int ret;
2080
2081   print (vam->ofp,
2082          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2083          "interface name", "sw_if_index", "mode", "load balance",
2084          "active slaves", "slaves");
2085
2086   /* Get list of bond interfaces */
2087   M (SW_INTERFACE_BOND_DUMP, mp);
2088   S (mp);
2089
2090   /* Use a control ping for synchronization */
2091   MPING (CONTROL_PING, mp_ping);
2092   S (mp_ping);
2093
2094   W (ret);
2095   return ret;
2096 }
2097
2098 static void vl_api_sw_interface_slave_details_t_handler
2099   (vl_api_sw_interface_slave_details_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102
2103   print (vam->ofp,
2104          "%-25s %-12d %-12d %d", mp->interface_name,
2105          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2106 }
2107
2108 static void vl_api_sw_interface_slave_details_t_handler_json
2109   (vl_api_sw_interface_slave_details_t * mp)
2110 {
2111   vat_main_t *vam = &vat_main;
2112   vat_json_node_t *node = NULL;
2113
2114   if (VAT_JSON_ARRAY != vam->json_tree.type)
2115     {
2116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2117       vat_json_init_array (&vam->json_tree);
2118     }
2119   node = vat_json_array_add (&vam->json_tree);
2120
2121   vat_json_init_object (node);
2122   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2123   vat_json_object_add_string_copy (node, "interface_name",
2124                                    mp->interface_name);
2125   vat_json_object_add_uint (node, "passive", mp->is_passive);
2126   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2127 }
2128
2129 static int
2130 api_sw_interface_slave_dump (vat_main_t * vam)
2131 {
2132   unformat_input_t *i = vam->input;
2133   vl_api_sw_interface_slave_dump_t *mp;
2134   vl_api_control_ping_t *mp_ping;
2135   u32 sw_if_index = ~0;
2136   u8 sw_if_index_set = 0;
2137   int ret;
2138
2139   /* Parse args required to build the message */
2140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2141     {
2142       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2143         sw_if_index_set = 1;
2144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2145         sw_if_index_set = 1;
2146       else
2147         break;
2148     }
2149
2150   if (sw_if_index_set == 0)
2151     {
2152       errmsg ("missing vpp interface name. ");
2153       return -99;
2154     }
2155
2156   print (vam->ofp,
2157          "\n%-25s %-12s %-12s %s",
2158          "slave interface name", "sw_if_index", "passive", "long_timeout");
2159
2160   /* Get list of bond interfaces */
2161   M (SW_INTERFACE_SLAVE_DUMP, mp);
2162   mp->sw_if_index = ntohl (sw_if_index);
2163   S (mp);
2164
2165   /* Use a control ping for synchronization */
2166   MPING (CONTROL_PING, mp_ping);
2167   S (mp_ping);
2168
2169   W (ret);
2170   return ret;
2171 }
2172
2173 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2174   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2175 {
2176   vat_main_t *vam = &vat_main;
2177   i32 retval = ntohl (mp->retval);
2178   if (vam->async_mode)
2179     {
2180       vam->async_errors += (retval < 0);
2181     }
2182   else
2183     {
2184       vam->retval = retval;
2185       vam->sw_if_index = ntohl (mp->sw_if_index);
2186       vam->result_ready = 1;
2187     }
2188   vam->regenerate_interface_table = 1;
2189 }
2190
2191 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2192   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   vat_json_node_t node;
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2200                             ntohl (mp->sw_if_index));
2201
2202   vat_json_print (vam->ofp, &node);
2203   vat_json_free (&node);
2204
2205   vam->retval = ntohl (mp->retval);
2206   vam->result_ready = 1;
2207 }
2208
2209 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2210   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   i32 retval = ntohl (mp->retval);
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->sw_if_index = ntohl (mp->sw_if_index);
2222       vam->result_ready = 1;
2223     }
2224 }
2225
2226 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2227   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2228 {
2229   vat_main_t *vam = &vat_main;
2230   vat_json_node_t node;
2231
2232   vat_json_init_object (&node);
2233   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2234   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2235
2236   vat_json_print (vam->ofp, &node);
2237   vat_json_free (&node);
2238
2239   vam->retval = ntohl (mp->retval);
2240   vam->result_ready = 1;
2241 }
2242
2243 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2244   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2245 {
2246   vat_main_t *vam = &vat_main;
2247   i32 retval = ntohl (mp->retval);
2248   if (vam->async_mode)
2249     {
2250       vam->async_errors += (retval < 0);
2251     }
2252   else
2253     {
2254       vam->retval = retval;
2255       vam->result_ready = 1;
2256     }
2257 }
2258
2259 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2260   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   vat_json_node_t node;
2264
2265   vat_json_init_object (&node);
2266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2267   vat_json_object_add_uint (&node, "fwd_entry_index",
2268                             clib_net_to_host_u32 (mp->fwd_entry_index));
2269
2270   vat_json_print (vam->ofp, &node);
2271   vat_json_free (&node);
2272
2273   vam->retval = ntohl (mp->retval);
2274   vam->result_ready = 1;
2275 }
2276
2277 u8 *
2278 format_lisp_transport_protocol (u8 * s, va_list * args)
2279 {
2280   u32 proto = va_arg (*args, u32);
2281
2282   switch (proto)
2283     {
2284     case 1:
2285       return format (s, "udp");
2286     case 2:
2287       return format (s, "api");
2288     default:
2289       return 0;
2290     }
2291   return 0;
2292 }
2293
2294 static void vl_api_one_get_transport_protocol_reply_t_handler
2295   (vl_api_one_get_transport_protocol_reply_t * mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   i32 retval = ntohl (mp->retval);
2299   if (vam->async_mode)
2300     {
2301       vam->async_errors += (retval < 0);
2302     }
2303   else
2304     {
2305       u32 proto = mp->protocol;
2306       print (vam->ofp, "Transport protocol: %U",
2307              format_lisp_transport_protocol, proto);
2308       vam->retval = retval;
2309       vam->result_ready = 1;
2310     }
2311 }
2312
2313 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2314   (vl_api_one_get_transport_protocol_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vat_json_node_t node;
2318   u8 *s;
2319
2320   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2321   vec_add1 (s, 0);
2322
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2326
2327   vec_free (s);
2328   vat_json_print (vam->ofp, &node);
2329   vat_json_free (&node);
2330
2331   vam->retval = ntohl (mp->retval);
2332   vam->result_ready = 1;
2333 }
2334
2335 static void vl_api_one_add_del_locator_set_reply_t_handler
2336   (vl_api_one_add_del_locator_set_reply_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   i32 retval = ntohl (mp->retval);
2340   if (vam->async_mode)
2341     {
2342       vam->async_errors += (retval < 0);
2343     }
2344   else
2345     {
2346       vam->retval = retval;
2347       vam->result_ready = 1;
2348     }
2349 }
2350
2351 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2352   (vl_api_one_add_del_locator_set_reply_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   vat_json_node_t node;
2356
2357   vat_json_init_object (&node);
2358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2359   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2360
2361   vat_json_print (vam->ofp, &node);
2362   vat_json_free (&node);
2363
2364   vam->retval = ntohl (mp->retval);
2365   vam->result_ready = 1;
2366 }
2367
2368 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2369   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   i32 retval = ntohl (mp->retval);
2373   if (vam->async_mode)
2374     {
2375       vam->async_errors += (retval < 0);
2376     }
2377   else
2378     {
2379       vam->retval = retval;
2380       vam->sw_if_index = ntohl (mp->sw_if_index);
2381       vam->result_ready = 1;
2382     }
2383   vam->regenerate_interface_table = 1;
2384 }
2385
2386 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2387   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390   vat_json_node_t node;
2391
2392   vat_json_init_object (&node);
2393   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2394   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2395
2396   vat_json_print (vam->ofp, &node);
2397   vat_json_free (&node);
2398
2399   vam->retval = ntohl (mp->retval);
2400   vam->result_ready = 1;
2401 }
2402
2403 static void vl_api_vxlan_offload_rx_reply_t_handler
2404   (vl_api_vxlan_offload_rx_reply_t * mp)
2405 {
2406   vat_main_t *vam = &vat_main;
2407   i32 retval = ntohl (mp->retval);
2408   if (vam->async_mode)
2409     {
2410       vam->async_errors += (retval < 0);
2411     }
2412   else
2413     {
2414       vam->retval = retval;
2415       vam->result_ready = 1;
2416     }
2417 }
2418
2419 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2420   (vl_api_vxlan_offload_rx_reply_t * mp)
2421 {
2422   vat_main_t *vam = &vat_main;
2423   vat_json_node_t node;
2424
2425   vat_json_init_object (&node);
2426   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2427
2428   vat_json_print (vam->ofp, &node);
2429   vat_json_free (&node);
2430
2431   vam->retval = ntohl (mp->retval);
2432   vam->result_ready = 1;
2433 }
2434
2435 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2436   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   i32 retval = ntohl (mp->retval);
2440   if (vam->async_mode)
2441     {
2442       vam->async_errors += (retval < 0);
2443     }
2444   else
2445     {
2446       vam->retval = retval;
2447       vam->sw_if_index = ntohl (mp->sw_if_index);
2448       vam->result_ready = 1;
2449     }
2450 }
2451
2452 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2453   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   vat_json_node_t node;
2457
2458   vat_json_init_object (&node);
2459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462   vat_json_print (vam->ofp, &node);
2463   vat_json_free (&node);
2464
2465   vam->retval = ntohl (mp->retval);
2466   vam->result_ready = 1;
2467 }
2468
2469 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2470   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   i32 retval = ntohl (mp->retval);
2474   if (vam->async_mode)
2475     {
2476       vam->async_errors += (retval < 0);
2477     }
2478   else
2479     {
2480       vam->retval = retval;
2481       vam->sw_if_index = ntohl (mp->sw_if_index);
2482       vam->result_ready = 1;
2483     }
2484   vam->regenerate_interface_table = 1;
2485 }
2486
2487 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2488   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2489 {
2490   vat_main_t *vam = &vat_main;
2491   vat_json_node_t node;
2492
2493   vat_json_init_object (&node);
2494   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2495   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2496
2497   vat_json_print (vam->ofp, &node);
2498   vat_json_free (&node);
2499
2500   vam->retval = ntohl (mp->retval);
2501   vam->result_ready = 1;
2502 }
2503
2504 static void vl_api_gre_tunnel_add_del_reply_t_handler
2505   (vl_api_gre_tunnel_add_del_reply_t * mp)
2506 {
2507   vat_main_t *vam = &vat_main;
2508   i32 retval = ntohl (mp->retval);
2509   if (vam->async_mode)
2510     {
2511       vam->async_errors += (retval < 0);
2512     }
2513   else
2514     {
2515       vam->retval = retval;
2516       vam->sw_if_index = ntohl (mp->sw_if_index);
2517       vam->result_ready = 1;
2518     }
2519 }
2520
2521 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2522   (vl_api_gre_tunnel_add_del_reply_t * mp)
2523 {
2524   vat_main_t *vam = &vat_main;
2525   vat_json_node_t node;
2526
2527   vat_json_init_object (&node);
2528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2529   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2530
2531   vat_json_print (vam->ofp, &node);
2532   vat_json_free (&node);
2533
2534   vam->retval = ntohl (mp->retval);
2535   vam->result_ready = 1;
2536 }
2537
2538 static void vl_api_create_vhost_user_if_reply_t_handler
2539   (vl_api_create_vhost_user_if_reply_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   i32 retval = ntohl (mp->retval);
2543   if (vam->async_mode)
2544     {
2545       vam->async_errors += (retval < 0);
2546     }
2547   else
2548     {
2549       vam->retval = retval;
2550       vam->sw_if_index = ntohl (mp->sw_if_index);
2551       vam->result_ready = 1;
2552     }
2553   vam->regenerate_interface_table = 1;
2554 }
2555
2556 static void vl_api_create_vhost_user_if_reply_t_handler_json
2557   (vl_api_create_vhost_user_if_reply_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560   vat_json_node_t node;
2561
2562   vat_json_init_object (&node);
2563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2564   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2565
2566   vat_json_print (vam->ofp, &node);
2567   vat_json_free (&node);
2568
2569   vam->retval = ntohl (mp->retval);
2570   vam->result_ready = 1;
2571 }
2572
2573 static void vl_api_dns_resolve_name_reply_t_handler
2574   (vl_api_dns_resolve_name_reply_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   i32 retval = ntohl (mp->retval);
2578   if (vam->async_mode)
2579     {
2580       vam->async_errors += (retval < 0);
2581     }
2582   else
2583     {
2584       vam->retval = retval;
2585       vam->result_ready = 1;
2586
2587       if (retval == 0)
2588         {
2589           if (mp->ip4_set)
2590             clib_warning ("ip4 address %U", format_ip4_address,
2591                           (ip4_address_t *) mp->ip4_address);
2592           if (mp->ip6_set)
2593             clib_warning ("ip6 address %U", format_ip6_address,
2594                           (ip6_address_t *) mp->ip6_address);
2595         }
2596       else
2597         clib_warning ("retval %d", retval);
2598     }
2599 }
2600
2601 static void vl_api_dns_resolve_name_reply_t_handler_json
2602   (vl_api_dns_resolve_name_reply_t * mp)
2603 {
2604   clib_warning ("not implemented");
2605 }
2606
2607 static void vl_api_dns_resolve_ip_reply_t_handler
2608   (vl_api_dns_resolve_ip_reply_t * mp)
2609 {
2610   vat_main_t *vam = &vat_main;
2611   i32 retval = ntohl (mp->retval);
2612   if (vam->async_mode)
2613     {
2614       vam->async_errors += (retval < 0);
2615     }
2616   else
2617     {
2618       vam->retval = retval;
2619       vam->result_ready = 1;
2620
2621       if (retval == 0)
2622         {
2623           clib_warning ("canonical name %s", mp->name);
2624         }
2625       else
2626         clib_warning ("retval %d", retval);
2627     }
2628 }
2629
2630 static void vl_api_dns_resolve_ip_reply_t_handler_json
2631   (vl_api_dns_resolve_ip_reply_t * mp)
2632 {
2633   clib_warning ("not implemented");
2634 }
2635
2636
2637 static void vl_api_ip_address_details_t_handler
2638   (vl_api_ip_address_details_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   static ip_address_details_t empty_ip_address_details = { {0} };
2642   ip_address_details_t *address = NULL;
2643   ip_details_t *current_ip_details = NULL;
2644   ip_details_t *details = NULL;
2645
2646   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2647
2648   if (!details || vam->current_sw_if_index >= vec_len (details)
2649       || !details[vam->current_sw_if_index].present)
2650     {
2651       errmsg ("ip address details arrived but not stored");
2652       errmsg ("ip_dump should be called first");
2653       return;
2654     }
2655
2656   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2657
2658 #define addresses (current_ip_details->addr)
2659
2660   vec_validate_init_empty (addresses, vec_len (addresses),
2661                            empty_ip_address_details);
2662
2663   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2664
2665   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2666   address->prefix_length = mp->prefix.len;
2667 #undef addresses
2668 }
2669
2670 static void vl_api_ip_address_details_t_handler_json
2671   (vl_api_ip_address_details_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   vat_json_node_t *node = NULL;
2675
2676   if (VAT_JSON_ARRAY != vam->json_tree.type)
2677     {
2678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2679       vat_json_init_array (&vam->json_tree);
2680     }
2681   node = vat_json_array_add (&vam->json_tree);
2682
2683   vat_json_init_object (node);
2684   vat_json_object_add_prefix (node, &mp->prefix);
2685 }
2686
2687 static void
2688 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   static ip_details_t empty_ip_details = { 0 };
2692   ip_details_t *ip = NULL;
2693   u32 sw_if_index = ~0;
2694
2695   sw_if_index = ntohl (mp->sw_if_index);
2696
2697   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2698                            sw_if_index, empty_ip_details);
2699
2700   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2701                          sw_if_index);
2702
2703   ip->present = 1;
2704 }
2705
2706 static void
2707 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710
2711   if (VAT_JSON_ARRAY != vam->json_tree.type)
2712     {
2713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2714       vat_json_init_array (&vam->json_tree);
2715     }
2716   vat_json_array_add_uint (&vam->json_tree,
2717                            clib_net_to_host_u32 (mp->sw_if_index));
2718 }
2719
2720 static void
2721 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2722 {
2723   u8 *s, i;
2724
2725   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2726               "host_mac %U router_addr %U",
2727               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2728               mp->lease.hostname,
2729               format_ip4_address, mp->lease.host_address,
2730               format_ethernet_address, mp->lease.host_mac,
2731               format_ip4_address, mp->lease.router_address);
2732
2733   for (i = 0; i < mp->lease.count; i++)
2734     s =
2735       format (s, " domain_server_addr %U", format_ip4_address,
2736               mp->lease.domain_server[i].address);
2737
2738   errmsg ((char *) s);
2739   vec_free (s);
2740 }
2741
2742 static void vl_api_dhcp_compl_event_t_handler_json
2743   (vl_api_dhcp_compl_event_t * mp)
2744 {
2745   /* JSON output not supported */
2746 }
2747
2748 static void vl_api_get_first_msg_id_reply_t_handler
2749   (vl_api_get_first_msg_id_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   i32 retval = ntohl (mp->retval);
2753
2754   if (vam->async_mode)
2755     {
2756       vam->async_errors += (retval < 0);
2757     }
2758   else
2759     {
2760       vam->retval = retval;
2761       vam->result_ready = 1;
2762     }
2763   if (retval >= 0)
2764     {
2765       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2766     }
2767 }
2768
2769 static void vl_api_get_first_msg_id_reply_t_handler_json
2770   (vl_api_get_first_msg_id_reply_t * mp)
2771 {
2772   vat_main_t *vam = &vat_main;
2773   vat_json_node_t node;
2774
2775   vat_json_init_object (&node);
2776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2777   vat_json_object_add_uint (&node, "first_msg_id",
2778                             (uint) ntohs (mp->first_msg_id));
2779
2780   vat_json_print (vam->ofp, &node);
2781   vat_json_free (&node);
2782
2783   vam->retval = ntohl (mp->retval);
2784   vam->result_ready = 1;
2785 }
2786
2787 static void vl_api_get_node_graph_reply_t_handler
2788   (vl_api_get_node_graph_reply_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   api_main_t *am = &api_main;
2792   i32 retval = ntohl (mp->retval);
2793   u8 *pvt_copy, *reply;
2794   void *oldheap;
2795   vlib_node_t *node;
2796   int i;
2797
2798   if (vam->async_mode)
2799     {
2800       vam->async_errors += (retval < 0);
2801     }
2802   else
2803     {
2804       vam->retval = retval;
2805       vam->result_ready = 1;
2806     }
2807
2808   /* "Should never happen..." */
2809   if (retval != 0)
2810     return;
2811
2812   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2813   pvt_copy = vec_dup (reply);
2814
2815   /* Toss the shared-memory original... */
2816   pthread_mutex_lock (&am->vlib_rp->mutex);
2817   oldheap = svm_push_data_heap (am->vlib_rp);
2818
2819   vec_free (reply);
2820
2821   svm_pop_heap (oldheap);
2822   pthread_mutex_unlock (&am->vlib_rp->mutex);
2823
2824   if (vam->graph_nodes)
2825     {
2826       hash_free (vam->graph_node_index_by_name);
2827
2828       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2829         {
2830           node = vam->graph_nodes[0][i];
2831           vec_free (node->name);
2832           vec_free (node->next_nodes);
2833           vec_free (node);
2834         }
2835       vec_free (vam->graph_nodes[0]);
2836       vec_free (vam->graph_nodes);
2837     }
2838
2839   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2840   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2841   vec_free (pvt_copy);
2842
2843   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2844     {
2845       node = vam->graph_nodes[0][i];
2846       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2847     }
2848 }
2849
2850 static void vl_api_get_node_graph_reply_t_handler_json
2851   (vl_api_get_node_graph_reply_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854   api_main_t *am = &api_main;
2855   void *oldheap;
2856   vat_json_node_t node;
2857   u8 *reply;
2858
2859   /* $$$$ make this real? */
2860   vat_json_init_object (&node);
2861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2862   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2863
2864   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2865
2866   /* Toss the shared-memory original... */
2867   pthread_mutex_lock (&am->vlib_rp->mutex);
2868   oldheap = svm_push_data_heap (am->vlib_rp);
2869
2870   vec_free (reply);
2871
2872   svm_pop_heap (oldheap);
2873   pthread_mutex_unlock (&am->vlib_rp->mutex);
2874
2875   vat_json_print (vam->ofp, &node);
2876   vat_json_free (&node);
2877
2878   vam->retval = ntohl (mp->retval);
2879   vam->result_ready = 1;
2880 }
2881
2882 static void
2883 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   u8 *s = 0;
2887
2888   if (mp->local)
2889     {
2890       s = format (s, "%=16d%=16d%=16d",
2891                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2892     }
2893   else
2894     {
2895       s = format (s, "%=16U%=16d%=16d",
2896                   mp->is_ipv6 ? format_ip6_address :
2897                   format_ip4_address,
2898                   mp->ip_address, mp->priority, mp->weight);
2899     }
2900
2901   print (vam->ofp, "%v", s);
2902   vec_free (s);
2903 }
2904
2905 static void
2906 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2907 {
2908   vat_main_t *vam = &vat_main;
2909   vat_json_node_t *node = NULL;
2910   struct in6_addr ip6;
2911   struct in_addr ip4;
2912
2913   if (VAT_JSON_ARRAY != vam->json_tree.type)
2914     {
2915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2916       vat_json_init_array (&vam->json_tree);
2917     }
2918   node = vat_json_array_add (&vam->json_tree);
2919   vat_json_init_object (node);
2920
2921   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2922   vat_json_object_add_uint (node, "priority", mp->priority);
2923   vat_json_object_add_uint (node, "weight", mp->weight);
2924
2925   if (mp->local)
2926     vat_json_object_add_uint (node, "sw_if_index",
2927                               clib_net_to_host_u32 (mp->sw_if_index));
2928   else
2929     {
2930       if (mp->is_ipv6)
2931         {
2932           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2933           vat_json_object_add_ip6 (node, "address", ip6);
2934         }
2935       else
2936         {
2937           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2938           vat_json_object_add_ip4 (node, "address", ip4);
2939         }
2940     }
2941 }
2942
2943 static void
2944 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2945                                           mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   u8 *ls_name = 0;
2949
2950   ls_name = format (0, "%s", mp->ls_name);
2951
2952   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2953          ls_name);
2954   vec_free (ls_name);
2955 }
2956
2957 static void
2958   vl_api_one_locator_set_details_t_handler_json
2959   (vl_api_one_locator_set_details_t * mp)
2960 {
2961   vat_main_t *vam = &vat_main;
2962   vat_json_node_t *node = 0;
2963   u8 *ls_name = 0;
2964
2965   ls_name = format (0, "%s", mp->ls_name);
2966   vec_add1 (ls_name, 0);
2967
2968   if (VAT_JSON_ARRAY != vam->json_tree.type)
2969     {
2970       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2971       vat_json_init_array (&vam->json_tree);
2972     }
2973   node = vat_json_array_add (&vam->json_tree);
2974
2975   vat_json_init_object (node);
2976   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2977   vat_json_object_add_uint (node, "ls_index",
2978                             clib_net_to_host_u32 (mp->ls_index));
2979   vec_free (ls_name);
2980 }
2981
2982 typedef struct
2983 {
2984   u32 spi;
2985   u8 si;
2986 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2987
2988 uword
2989 unformat_nsh_address (unformat_input_t * input, va_list * args)
2990 {
2991   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2992   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2993 }
2994
2995 u8 *
2996 format_nsh_address_vat (u8 * s, va_list * args)
2997 {
2998   nsh_t *a = va_arg (*args, nsh_t *);
2999   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3000 }
3001
3002 static u8 *
3003 format_lisp_flat_eid (u8 * s, va_list * args)
3004 {
3005   u32 type = va_arg (*args, u32);
3006   u8 *eid = va_arg (*args, u8 *);
3007   u32 eid_len = va_arg (*args, u32);
3008
3009   switch (type)
3010     {
3011     case 0:
3012       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3013     case 1:
3014       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3015     case 2:
3016       return format (s, "%U", format_ethernet_address, eid);
3017     case 3:
3018       return format (s, "%U", format_nsh_address_vat, eid);
3019     }
3020   return 0;
3021 }
3022
3023 static u8 *
3024 format_lisp_eid_vat (u8 * s, va_list * args)
3025 {
3026   u32 type = va_arg (*args, u32);
3027   u8 *eid = va_arg (*args, u8 *);
3028   u32 eid_len = va_arg (*args, u32);
3029   u8 *seid = va_arg (*args, u8 *);
3030   u32 seid_len = va_arg (*args, u32);
3031   u32 is_src_dst = va_arg (*args, u32);
3032
3033   if (is_src_dst)
3034     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3035
3036   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3037
3038   return s;
3039 }
3040
3041 static void
3042 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3043 {
3044   vat_main_t *vam = &vat_main;
3045   u8 *s = 0, *eid = 0;
3046
3047   if (~0 == mp->locator_set_index)
3048     s = format (0, "action: %d", mp->action);
3049   else
3050     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3051
3052   eid = format (0, "%U", format_lisp_eid_vat,
3053                 mp->eid_type,
3054                 mp->eid,
3055                 mp->eid_prefix_len,
3056                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3057   vec_add1 (eid, 0);
3058
3059   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3060          clib_net_to_host_u32 (mp->vni),
3061          eid,
3062          mp->is_local ? "local" : "remote",
3063          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3064          clib_net_to_host_u16 (mp->key_id), mp->key);
3065
3066   vec_free (s);
3067   vec_free (eid);
3068 }
3069
3070 static void
3071 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3072                                              * mp)
3073 {
3074   vat_main_t *vam = &vat_main;
3075   vat_json_node_t *node = 0;
3076   u8 *eid = 0;
3077
3078   if (VAT_JSON_ARRAY != vam->json_tree.type)
3079     {
3080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3081       vat_json_init_array (&vam->json_tree);
3082     }
3083   node = vat_json_array_add (&vam->json_tree);
3084
3085   vat_json_init_object (node);
3086   if (~0 == mp->locator_set_index)
3087     vat_json_object_add_uint (node, "action", mp->action);
3088   else
3089     vat_json_object_add_uint (node, "locator_set_index",
3090                               clib_net_to_host_u32 (mp->locator_set_index));
3091
3092   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3093   if (mp->eid_type == 3)
3094     {
3095       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3096       vat_json_init_object (nsh_json);
3097       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3098       vat_json_object_add_uint (nsh_json, "spi",
3099                                 clib_net_to_host_u32 (nsh->spi));
3100       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3101     }
3102   else
3103     {
3104       eid = format (0, "%U", format_lisp_eid_vat,
3105                     mp->eid_type,
3106                     mp->eid,
3107                     mp->eid_prefix_len,
3108                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109       vec_add1 (eid, 0);
3110       vat_json_object_add_string_copy (node, "eid", eid);
3111       vec_free (eid);
3112     }
3113   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3114   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3115   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3116
3117   if (mp->key_id)
3118     {
3119       vat_json_object_add_uint (node, "key_id",
3120                                 clib_net_to_host_u16 (mp->key_id));
3121       vat_json_object_add_string_copy (node, "key", mp->key);
3122     }
3123 }
3124
3125 static void
3126 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   u8 *seid = 0, *deid = 0;
3130   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3131
3132   deid = format (0, "%U", format_lisp_eid_vat,
3133                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3134
3135   seid = format (0, "%U", format_lisp_eid_vat,
3136                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3137
3138   vec_add1 (deid, 0);
3139   vec_add1 (seid, 0);
3140
3141   if (mp->is_ip4)
3142     format_ip_address_fcn = format_ip4_address;
3143   else
3144     format_ip_address_fcn = format_ip6_address;
3145
3146
3147   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3148          clib_net_to_host_u32 (mp->vni),
3149          seid, deid,
3150          format_ip_address_fcn, mp->lloc,
3151          format_ip_address_fcn, mp->rloc,
3152          clib_net_to_host_u32 (mp->pkt_count),
3153          clib_net_to_host_u32 (mp->bytes));
3154
3155   vec_free (deid);
3156   vec_free (seid);
3157 }
3158
3159 static void
3160 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3161 {
3162   struct in6_addr ip6;
3163   struct in_addr ip4;
3164   vat_main_t *vam = &vat_main;
3165   vat_json_node_t *node = 0;
3166   u8 *deid = 0, *seid = 0;
3167
3168   if (VAT_JSON_ARRAY != vam->json_tree.type)
3169     {
3170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3171       vat_json_init_array (&vam->json_tree);
3172     }
3173   node = vat_json_array_add (&vam->json_tree);
3174
3175   vat_json_init_object (node);
3176   deid = format (0, "%U", format_lisp_eid_vat,
3177                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3178
3179   seid = format (0, "%U", format_lisp_eid_vat,
3180                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3181
3182   vec_add1 (deid, 0);
3183   vec_add1 (seid, 0);
3184
3185   vat_json_object_add_string_copy (node, "seid", seid);
3186   vat_json_object_add_string_copy (node, "deid", deid);
3187   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3188
3189   if (mp->is_ip4)
3190     {
3191       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3192       vat_json_object_add_ip4 (node, "lloc", ip4);
3193       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3194       vat_json_object_add_ip4 (node, "rloc", ip4);
3195     }
3196   else
3197     {
3198       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3199       vat_json_object_add_ip6 (node, "lloc", ip6);
3200       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3201       vat_json_object_add_ip6 (node, "rloc", ip6);
3202     }
3203   vat_json_object_add_uint (node, "pkt_count",
3204                             clib_net_to_host_u32 (mp->pkt_count));
3205   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212   vl_api_one_eid_table_map_details_t_handler
3213   (vl_api_one_eid_table_map_details_t * mp)
3214 {
3215   vat_main_t *vam = &vat_main;
3216
3217   u8 *line = format (0, "%=10d%=10d",
3218                      clib_net_to_host_u32 (mp->vni),
3219                      clib_net_to_host_u32 (mp->dp_table));
3220   print (vam->ofp, "%v", line);
3221   vec_free (line);
3222 }
3223
3224 static void
3225   vl_api_one_eid_table_map_details_t_handler_json
3226   (vl_api_one_eid_table_map_details_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   vat_json_node_t *node = NULL;
3230
3231   if (VAT_JSON_ARRAY != vam->json_tree.type)
3232     {
3233       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3234       vat_json_init_array (&vam->json_tree);
3235     }
3236   node = vat_json_array_add (&vam->json_tree);
3237   vat_json_init_object (node);
3238   vat_json_object_add_uint (node, "dp_table",
3239                             clib_net_to_host_u32 (mp->dp_table));
3240   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3241 }
3242
3243 static void
3244   vl_api_one_eid_table_vni_details_t_handler
3245   (vl_api_one_eid_table_vni_details_t * mp)
3246 {
3247   vat_main_t *vam = &vat_main;
3248
3249   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3250   print (vam->ofp, "%v", line);
3251   vec_free (line);
3252 }
3253
3254 static void
3255   vl_api_one_eid_table_vni_details_t_handler_json
3256   (vl_api_one_eid_table_vni_details_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   vat_json_node_t *node = NULL;
3260
3261   if (VAT_JSON_ARRAY != vam->json_tree.type)
3262     {
3263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3264       vat_json_init_array (&vam->json_tree);
3265     }
3266   node = vat_json_array_add (&vam->json_tree);
3267   vat_json_init_object (node);
3268   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3269 }
3270
3271 static void
3272   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3273   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3279   print (vam->ofp, "fallback threshold value: %d", mp->value);
3280
3281   vam->retval = retval;
3282   vam->result_ready = 1;
3283 }
3284
3285 static void
3286   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3287   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3288 {
3289   vat_main_t *vam = &vat_main;
3290   vat_json_node_t _node, *node = &_node;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3294   vat_json_init_object (node);
3295   vat_json_object_add_uint (node, "value", mp->value);
3296
3297   vat_json_print (vam->ofp, node);
3298   vat_json_free (node);
3299
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302 }
3303
3304 static void
3305   vl_api_show_one_map_register_state_reply_t_handler
3306   (vl_api_show_one_map_register_state_reply_t * mp)
3307 {
3308   vat_main_t *vam = &vat_main;
3309   int retval = clib_net_to_host_u32 (mp->retval);
3310
3311   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3312
3313   vam->retval = retval;
3314   vam->result_ready = 1;
3315 }
3316
3317 static void
3318   vl_api_show_one_map_register_state_reply_t_handler_json
3319   (vl_api_show_one_map_register_state_reply_t * mp)
3320 {
3321   vat_main_t *vam = &vat_main;
3322   vat_json_node_t _node, *node = &_node;
3323   int retval = clib_net_to_host_u32 (mp->retval);
3324
3325   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3326
3327   vat_json_init_object (node);
3328   vat_json_object_add_string_copy (node, "state", s);
3329
3330   vat_json_print (vam->ofp, node);
3331   vat_json_free (node);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335   vec_free (s);
3336 }
3337
3338 static void
3339   vl_api_show_one_rloc_probe_state_reply_t_handler
3340   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   if (retval)
3346     goto end;
3347
3348   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3349 end:
3350   vam->retval = retval;
3351   vam->result_ready = 1;
3352 }
3353
3354 static void
3355   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3356   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3357 {
3358   vat_main_t *vam = &vat_main;
3359   vat_json_node_t _node, *node = &_node;
3360   int retval = clib_net_to_host_u32 (mp->retval);
3361
3362   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3363   vat_json_init_object (node);
3364   vat_json_object_add_string_copy (node, "state", s);
3365
3366   vat_json_print (vam->ofp, node);
3367   vat_json_free (node);
3368
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371   vec_free (s);
3372 }
3373
3374 static void
3375   vl_api_show_one_stats_enable_disable_reply_t_handler
3376   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3377 {
3378   vat_main_t *vam = &vat_main;
3379   int retval = clib_net_to_host_u32 (mp->retval);
3380
3381   if (retval)
3382     goto end;
3383
3384   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3385 end:
3386   vam->retval = retval;
3387   vam->result_ready = 1;
3388 }
3389
3390 static void
3391   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3392   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   vat_json_node_t _node, *node = &_node;
3396   int retval = clib_net_to_host_u32 (mp->retval);
3397
3398   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3399   vat_json_init_object (node);
3400   vat_json_object_add_string_copy (node, "state", s);
3401
3402   vat_json_print (vam->ofp, node);
3403   vat_json_free (node);
3404
3405   vam->retval = retval;
3406   vam->result_ready = 1;
3407   vec_free (s);
3408 }
3409
3410 static void
3411 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3412 {
3413   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3414   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3415   e->vni = clib_net_to_host_u32 (e->vni);
3416 }
3417
3418 static void
3419   gpe_fwd_entries_get_reply_t_net_to_host
3420   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3421 {
3422   u32 i;
3423
3424   mp->count = clib_net_to_host_u32 (mp->count);
3425   for (i = 0; i < mp->count; i++)
3426     {
3427       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3428     }
3429 }
3430
3431 static u8 *
3432 format_gpe_encap_mode (u8 * s, va_list * args)
3433 {
3434   u32 mode = va_arg (*args, u32);
3435
3436   switch (mode)
3437     {
3438     case 0:
3439       return format (s, "lisp");
3440     case 1:
3441       return format (s, "vxlan");
3442     }
3443   return 0;
3444 }
3445
3446 static void
3447   vl_api_gpe_get_encap_mode_reply_t_handler
3448   (vl_api_gpe_get_encap_mode_reply_t * mp)
3449 {
3450   vat_main_t *vam = &vat_main;
3451
3452   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3453   vam->retval = ntohl (mp->retval);
3454   vam->result_ready = 1;
3455 }
3456
3457 static void
3458   vl_api_gpe_get_encap_mode_reply_t_handler_json
3459   (vl_api_gpe_get_encap_mode_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   vat_json_node_t node;
3463
3464   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3465   vec_add1 (encap_mode, 0);
3466
3467   vat_json_init_object (&node);
3468   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3469
3470   vec_free (encap_mode);
3471   vat_json_print (vam->ofp, &node);
3472   vat_json_free (&node);
3473
3474   vam->retval = ntohl (mp->retval);
3475   vam->result_ready = 1;
3476 }
3477
3478 static void
3479   vl_api_gpe_fwd_entry_path_details_t_handler
3480   (vl_api_gpe_fwd_entry_path_details_t * mp)
3481 {
3482   vat_main_t *vam = &vat_main;
3483   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3484
3485   if (mp->lcl_loc.is_ip4)
3486     format_ip_address_fcn = format_ip4_address;
3487   else
3488     format_ip_address_fcn = format_ip6_address;
3489
3490   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3491          format_ip_address_fcn, &mp->lcl_loc,
3492          format_ip_address_fcn, &mp->rmt_loc);
3493 }
3494
3495 static void
3496 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3497 {
3498   struct in6_addr ip6;
3499   struct in_addr ip4;
3500
3501   if (loc->is_ip4)
3502     {
3503       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3504       vat_json_object_add_ip4 (n, "address", ip4);
3505     }
3506   else
3507     {
3508       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3509       vat_json_object_add_ip6 (n, "address", ip6);
3510     }
3511   vat_json_object_add_uint (n, "weight", loc->weight);
3512 }
3513
3514 static void
3515   vl_api_gpe_fwd_entry_path_details_t_handler_json
3516   (vl_api_gpe_fwd_entry_path_details_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   vat_json_node_t *node = NULL;
3520   vat_json_node_t *loc_node;
3521
3522   if (VAT_JSON_ARRAY != vam->json_tree.type)
3523     {
3524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3525       vat_json_init_array (&vam->json_tree);
3526     }
3527   node = vat_json_array_add (&vam->json_tree);
3528   vat_json_init_object (node);
3529
3530   loc_node = vat_json_object_add (node, "local_locator");
3531   vat_json_init_object (loc_node);
3532   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3533
3534   loc_node = vat_json_object_add (node, "remote_locator");
3535   vat_json_init_object (loc_node);
3536   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3537 }
3538
3539 static void
3540   vl_api_gpe_fwd_entries_get_reply_t_handler
3541   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3542 {
3543   vat_main_t *vam = &vat_main;
3544   u32 i;
3545   int retval = clib_net_to_host_u32 (mp->retval);
3546   vl_api_gpe_fwd_entry_t *e;
3547
3548   if (retval)
3549     goto end;
3550
3551   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3552
3553   for (i = 0; i < mp->count; i++)
3554     {
3555       e = &mp->entries[i];
3556       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3557              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3558              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3559     }
3560
3561 end:
3562   vam->retval = retval;
3563   vam->result_ready = 1;
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3568   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3569 {
3570   u8 *s = 0;
3571   vat_main_t *vam = &vat_main;
3572   vat_json_node_t *e = 0, root;
3573   u32 i;
3574   int retval = clib_net_to_host_u32 (mp->retval);
3575   vl_api_gpe_fwd_entry_t *fwd;
3576
3577   if (retval)
3578     goto end;
3579
3580   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3581   vat_json_init_array (&root);
3582
3583   for (i = 0; i < mp->count; i++)
3584     {
3585       e = vat_json_array_add (&root);
3586       fwd = &mp->entries[i];
3587
3588       vat_json_init_object (e);
3589       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3590       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3591       vat_json_object_add_int (e, "vni", fwd->vni);
3592       vat_json_object_add_int (e, "action", fwd->action);
3593
3594       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3595                   fwd->leid_prefix_len);
3596       vec_add1 (s, 0);
3597       vat_json_object_add_string_copy (e, "leid", s);
3598       vec_free (s);
3599
3600       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3601                   fwd->reid_prefix_len);
3602       vec_add1 (s, 0);
3603       vat_json_object_add_string_copy (e, "reid", s);
3604       vec_free (s);
3605     }
3606
3607   vat_json_print (vam->ofp, &root);
3608   vat_json_free (&root);
3609
3610 end:
3611   vam->retval = retval;
3612   vam->result_ready = 1;
3613 }
3614
3615 static void
3616   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3617   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620   u32 i, n;
3621   int retval = clib_net_to_host_u32 (mp->retval);
3622   vl_api_gpe_native_fwd_rpath_t *r;
3623
3624   if (retval)
3625     goto end;
3626
3627   n = clib_net_to_host_u32 (mp->count);
3628
3629   for (i = 0; i < n; i++)
3630     {
3631       r = &mp->entries[i];
3632       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3633              clib_net_to_host_u32 (r->fib_index),
3634              clib_net_to_host_u32 (r->nh_sw_if_index),
3635              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3636     }
3637
3638 end:
3639   vam->retval = retval;
3640   vam->result_ready = 1;
3641 }
3642
3643 static void
3644   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3645   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3646 {
3647   vat_main_t *vam = &vat_main;
3648   vat_json_node_t root, *e;
3649   u32 i, n;
3650   int retval = clib_net_to_host_u32 (mp->retval);
3651   vl_api_gpe_native_fwd_rpath_t *r;
3652   u8 *s;
3653
3654   if (retval)
3655     goto end;
3656
3657   n = clib_net_to_host_u32 (mp->count);
3658   vat_json_init_array (&root);
3659
3660   for (i = 0; i < n; i++)
3661     {
3662       e = vat_json_array_add (&root);
3663       vat_json_init_object (e);
3664       r = &mp->entries[i];
3665       s =
3666         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3667                 r->nh_addr);
3668       vec_add1 (s, 0);
3669       vat_json_object_add_string_copy (e, "ip4", s);
3670       vec_free (s);
3671
3672       vat_json_object_add_uint (e, "fib_index",
3673                                 clib_net_to_host_u32 (r->fib_index));
3674       vat_json_object_add_uint (e, "nh_sw_if_index",
3675                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3676     }
3677
3678   vat_json_print (vam->ofp, &root);
3679   vat_json_free (&root);
3680
3681 end:
3682   vam->retval = retval;
3683   vam->result_ready = 1;
3684 }
3685
3686 static void
3687   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3688   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   u32 i, n;
3692   int retval = clib_net_to_host_u32 (mp->retval);
3693
3694   if (retval)
3695     goto end;
3696
3697   n = clib_net_to_host_u32 (mp->count);
3698
3699   for (i = 0; i < n; i++)
3700     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3701
3702 end:
3703   vam->retval = retval;
3704   vam->result_ready = 1;
3705 }
3706
3707 static void
3708   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3709   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3710 {
3711   vat_main_t *vam = &vat_main;
3712   vat_json_node_t root;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715
3716   if (retval)
3717     goto end;
3718
3719   n = clib_net_to_host_u32 (mp->count);
3720   vat_json_init_array (&root);
3721
3722   for (i = 0; i < n; i++)
3723     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3724
3725   vat_json_print (vam->ofp, &root);
3726   vat_json_free (&root);
3727
3728 end:
3729   vam->retval = retval;
3730   vam->result_ready = 1;
3731 }
3732
3733 static void
3734   vl_api_one_ndp_entries_get_reply_t_handler
3735   (vl_api_one_ndp_entries_get_reply_t * mp)
3736 {
3737   vat_main_t *vam = &vat_main;
3738   u32 i, n;
3739   int retval = clib_net_to_host_u32 (mp->retval);
3740
3741   if (retval)
3742     goto end;
3743
3744   n = clib_net_to_host_u32 (mp->count);
3745
3746   for (i = 0; i < n; i++)
3747     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3748            format_ethernet_address, mp->entries[i].mac);
3749
3750 end:
3751   vam->retval = retval;
3752   vam->result_ready = 1;
3753 }
3754
3755 static void
3756   vl_api_one_ndp_entries_get_reply_t_handler_json
3757   (vl_api_one_ndp_entries_get_reply_t * mp)
3758 {
3759   u8 *s = 0;
3760   vat_main_t *vam = &vat_main;
3761   vat_json_node_t *e = 0, root;
3762   u32 i, n;
3763   int retval = clib_net_to_host_u32 (mp->retval);
3764   vl_api_one_ndp_entry_t *arp_entry;
3765
3766   if (retval)
3767     goto end;
3768
3769   n = clib_net_to_host_u32 (mp->count);
3770   vat_json_init_array (&root);
3771
3772   for (i = 0; i < n; i++)
3773     {
3774       e = vat_json_array_add (&root);
3775       arp_entry = &mp->entries[i];
3776
3777       vat_json_init_object (e);
3778       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3779       vec_add1 (s, 0);
3780
3781       vat_json_object_add_string_copy (e, "mac", s);
3782       vec_free (s);
3783
3784       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3785       vec_add1 (s, 0);
3786       vat_json_object_add_string_copy (e, "ip6", s);
3787       vec_free (s);
3788     }
3789
3790   vat_json_print (vam->ofp, &root);
3791   vat_json_free (&root);
3792
3793 end:
3794   vam->retval = retval;
3795   vam->result_ready = 1;
3796 }
3797
3798 static void
3799   vl_api_one_l2_arp_entries_get_reply_t_handler
3800   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3801 {
3802   vat_main_t *vam = &vat_main;
3803   u32 i, n;
3804   int retval = clib_net_to_host_u32 (mp->retval);
3805
3806   if (retval)
3807     goto end;
3808
3809   n = clib_net_to_host_u32 (mp->count);
3810
3811   for (i = 0; i < n; i++)
3812     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3813            format_ethernet_address, mp->entries[i].mac);
3814
3815 end:
3816   vam->retval = retval;
3817   vam->result_ready = 1;
3818 }
3819
3820 static void
3821   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3822   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3823 {
3824   u8 *s = 0;
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t *e = 0, root;
3827   u32 i, n;
3828   int retval = clib_net_to_host_u32 (mp->retval);
3829   vl_api_one_l2_arp_entry_t *arp_entry;
3830
3831   if (retval)
3832     goto end;
3833
3834   n = clib_net_to_host_u32 (mp->count);
3835   vat_json_init_array (&root);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       e = vat_json_array_add (&root);
3840       arp_entry = &mp->entries[i];
3841
3842       vat_json_init_object (e);
3843       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3844       vec_add1 (s, 0);
3845
3846       vat_json_object_add_string_copy (e, "mac", s);
3847       vec_free (s);
3848
3849       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3850       vec_add1 (s, 0);
3851       vat_json_object_add_string_copy (e, "ip4", s);
3852       vec_free (s);
3853     }
3854
3855   vat_json_print (vam->ofp, &root);
3856   vat_json_free (&root);
3857
3858 end:
3859   vam->retval = retval;
3860   vam->result_ready = 1;
3861 }
3862
3863 static void
3864 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874
3875   for (i = 0; i < n; i++)
3876     {
3877       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880 end:
3881   vam->retval = retval;
3882   vam->result_ready = 1;
3883 }
3884
3885 static void
3886   vl_api_one_ndp_bd_get_reply_t_handler_json
3887   (vl_api_one_ndp_bd_get_reply_t * mp)
3888 {
3889   vat_main_t *vam = &vat_main;
3890   vat_json_node_t root;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893
3894   if (retval)
3895     goto end;
3896
3897   n = clib_net_to_host_u32 (mp->count);
3898   vat_json_init_array (&root);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       vat_json_array_add_uint (&root,
3903                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3904     }
3905
3906   vat_json_print (vam->ofp, &root);
3907   vat_json_free (&root);
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_l2_arp_bd_get_reply_t_handler
3916   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3939   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_adjacencies_get_reply_t_handler
3968   (vl_api_one_adjacencies_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973   vl_api_one_adjacency_t *a;
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     {
3982       a = &mp->adjacencies[i];
3983       print (vam->ofp, "%U %40U",
3984              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3985              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3986     }
3987
3988 end:
3989   vam->retval = retval;
3990   vam->result_ready = 1;
3991 }
3992
3993 static void
3994   vl_api_one_adjacencies_get_reply_t_handler_json
3995   (vl_api_one_adjacencies_get_reply_t * mp)
3996 {
3997   u8 *s = 0;
3998   vat_main_t *vam = &vat_main;
3999   vat_json_node_t *e = 0, root;
4000   u32 i, n;
4001   int retval = clib_net_to_host_u32 (mp->retval);
4002   vl_api_one_adjacency_t *a;
4003
4004   if (retval)
4005     goto end;
4006
4007   n = clib_net_to_host_u32 (mp->count);
4008   vat_json_init_array (&root);
4009
4010   for (i = 0; i < n; i++)
4011     {
4012       e = vat_json_array_add (&root);
4013       a = &mp->adjacencies[i];
4014
4015       vat_json_init_object (e);
4016       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4017                   a->leid_prefix_len);
4018       vec_add1 (s, 0);
4019       vat_json_object_add_string_copy (e, "leid", s);
4020       vec_free (s);
4021
4022       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4023                   a->reid_prefix_len);
4024       vec_add1 (s, 0);
4025       vat_json_object_add_string_copy (e, "reid", s);
4026       vec_free (s);
4027     }
4028
4029   vat_json_print (vam->ofp, &root);
4030   vat_json_free (&root);
4031
4032 end:
4033   vam->retval = retval;
4034   vam->result_ready = 1;
4035 }
4036
4037 static void
4038 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041
4042   print (vam->ofp, "%=20U",
4043          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4044          mp->ip_address);
4045 }
4046
4047 static void
4048   vl_api_one_map_server_details_t_handler_json
4049   (vl_api_one_map_server_details_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t *node = NULL;
4053   struct in6_addr ip6;
4054   struct in_addr ip4;
4055
4056   if (VAT_JSON_ARRAY != vam->json_tree.type)
4057     {
4058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4059       vat_json_init_array (&vam->json_tree);
4060     }
4061   node = vat_json_array_add (&vam->json_tree);
4062
4063   vat_json_init_object (node);
4064   if (mp->is_ipv6)
4065     {
4066       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4067       vat_json_object_add_ip6 (node, "map-server", ip6);
4068     }
4069   else
4070     {
4071       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4072       vat_json_object_add_ip4 (node, "map-server", ip4);
4073     }
4074 }
4075
4076 static void
4077 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4078                                            * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081
4082   print (vam->ofp, "%=20U",
4083          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4084          mp->ip_address);
4085 }
4086
4087 static void
4088   vl_api_one_map_resolver_details_t_handler_json
4089   (vl_api_one_map_resolver_details_t * mp)
4090 {
4091   vat_main_t *vam = &vat_main;
4092   vat_json_node_t *node = NULL;
4093   struct in6_addr ip6;
4094   struct in_addr ip4;
4095
4096   if (VAT_JSON_ARRAY != vam->json_tree.type)
4097     {
4098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4099       vat_json_init_array (&vam->json_tree);
4100     }
4101   node = vat_json_array_add (&vam->json_tree);
4102
4103   vat_json_init_object (node);
4104   if (mp->is_ipv6)
4105     {
4106       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4107       vat_json_object_add_ip6 (node, "map resolver", ip6);
4108     }
4109   else
4110     {
4111       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4112       vat_json_object_add_ip4 (node, "map resolver", ip4);
4113     }
4114 }
4115
4116 static void
4117 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4118 {
4119   vat_main_t *vam = &vat_main;
4120   i32 retval = ntohl (mp->retval);
4121
4122   if (0 <= retval)
4123     {
4124       print (vam->ofp, "feature: %s\ngpe: %s",
4125              mp->feature_status ? "enabled" : "disabled",
4126              mp->gpe_status ? "enabled" : "disabled");
4127     }
4128
4129   vam->retval = retval;
4130   vam->result_ready = 1;
4131 }
4132
4133 static void
4134   vl_api_show_one_status_reply_t_handler_json
4135   (vl_api_show_one_status_reply_t * mp)
4136 {
4137   vat_main_t *vam = &vat_main;
4138   vat_json_node_t node;
4139   u8 *gpe_status = NULL;
4140   u8 *feature_status = NULL;
4141
4142   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4143   feature_status = format (0, "%s",
4144                            mp->feature_status ? "enabled" : "disabled");
4145   vec_add1 (gpe_status, 0);
4146   vec_add1 (feature_status, 0);
4147
4148   vat_json_init_object (&node);
4149   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4150   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4151
4152   vec_free (gpe_status);
4153   vec_free (feature_status);
4154
4155   vat_json_print (vam->ofp, &node);
4156   vat_json_free (&node);
4157
4158   vam->retval = ntohl (mp->retval);
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4164   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   i32 retval = ntohl (mp->retval);
4168
4169   if (retval >= 0)
4170     {
4171       print (vam->ofp, "%=20s", mp->locator_set_name);
4172     }
4173
4174   vam->retval = retval;
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4180   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   vat_json_node_t *node = NULL;
4184
4185   if (VAT_JSON_ARRAY != vam->json_tree.type)
4186     {
4187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4188       vat_json_init_array (&vam->json_tree);
4189     }
4190   node = vat_json_array_add (&vam->json_tree);
4191
4192   vat_json_init_object (node);
4193   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4194
4195   vat_json_print (vam->ofp, node);
4196   vat_json_free (node);
4197
4198   vam->retval = ntohl (mp->retval);
4199   vam->result_ready = 1;
4200 }
4201
4202 static u8 *
4203 format_lisp_map_request_mode (u8 * s, va_list * args)
4204 {
4205   u32 mode = va_arg (*args, u32);
4206
4207   switch (mode)
4208     {
4209     case 0:
4210       return format (0, "dst-only");
4211     case 1:
4212       return format (0, "src-dst");
4213     }
4214   return 0;
4215 }
4216
4217 static void
4218   vl_api_show_one_map_request_mode_reply_t_handler
4219   (vl_api_show_one_map_request_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       u32 mode = mp->mode;
4227       print (vam->ofp, "map_request_mode: %U",
4228              format_lisp_map_request_mode, mode);
4229     }
4230
4231   vam->retval = retval;
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_show_one_map_request_mode_reply_t_handler_json
4237   (vl_api_show_one_map_request_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   vat_json_node_t node;
4241   u8 *s = 0;
4242   u32 mode;
4243
4244   mode = mp->mode;
4245   s = format (0, "%U", format_lisp_map_request_mode, mode);
4246   vec_add1 (s, 0);
4247
4248   vat_json_init_object (&node);
4249   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4250   vat_json_print (vam->ofp, &node);
4251   vat_json_free (&node);
4252
4253   vec_free (s);
4254   vam->retval = ntohl (mp->retval);
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_xtr_mode_reply_t_handler
4260   (vl_api_one_show_xtr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   i32 retval = ntohl (mp->retval);
4264
4265   if (0 <= retval)
4266     {
4267       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_xtr_mode_reply_t_handler_json
4276   (vl_api_one_show_xtr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281
4282   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4283   vec_add1 (status, 0);
4284
4285   vat_json_init_object (&node);
4286   vat_json_object_add_string_copy (&node, "status", status);
4287
4288   vec_free (status);
4289
4290   vat_json_print (vam->ofp, &node);
4291   vat_json_free (&node);
4292
4293   vam->retval = ntohl (mp->retval);
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_one_show_pitr_mode_reply_t_handler
4299   (vl_api_one_show_pitr_mode_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   i32 retval = ntohl (mp->retval);
4303
4304   if (0 <= retval)
4305     {
4306       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4307     }
4308
4309   vam->retval = retval;
4310   vam->result_ready = 1;
4311 }
4312
4313 static void
4314   vl_api_one_show_pitr_mode_reply_t_handler_json
4315   (vl_api_one_show_pitr_mode_reply_t * mp)
4316 {
4317   vat_main_t *vam = &vat_main;
4318   vat_json_node_t node;
4319   u8 *status = 0;
4320
4321   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326
4327   vec_free (status);
4328
4329   vat_json_print (vam->ofp, &node);
4330   vat_json_free (&node);
4331
4332   vam->retval = ntohl (mp->retval);
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_one_show_petr_mode_reply_t_handler
4338   (vl_api_one_show_petr_mode_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   i32 retval = ntohl (mp->retval);
4342
4343   if (0 <= retval)
4344     {
4345       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4346     }
4347
4348   vam->retval = retval;
4349   vam->result_ready = 1;
4350 }
4351
4352 static void
4353   vl_api_one_show_petr_mode_reply_t_handler_json
4354   (vl_api_one_show_petr_mode_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   vat_json_node_t node;
4358   u8 *status = 0;
4359
4360   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4361   vec_add1 (status, 0);
4362
4363   vat_json_init_object (&node);
4364   vat_json_object_add_string_copy (&node, "status", status);
4365
4366   vec_free (status);
4367
4368   vat_json_print (vam->ofp, &node);
4369   vat_json_free (&node);
4370
4371   vam->retval = ntohl (mp->retval);
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_use_petr_reply_t_handler
4377   (vl_api_show_one_use_petr_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   i32 retval = ntohl (mp->retval);
4381
4382   if (0 <= retval)
4383     {
4384       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4385       if (mp->status)
4386         {
4387           print (vam->ofp, "Proxy-ETR address; %U",
4388                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4389                  mp->address);
4390         }
4391     }
4392
4393   vam->retval = retval;
4394   vam->result_ready = 1;
4395 }
4396
4397 static void
4398   vl_api_show_one_use_petr_reply_t_handler_json
4399   (vl_api_show_one_use_petr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   vat_json_node_t node;
4403   u8 *status = 0;
4404   struct in_addr ip4;
4405   struct in6_addr ip6;
4406
4407   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "status", status);
4412   if (mp->status)
4413     {
4414       if (mp->is_ip4)
4415         {
4416           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4417           vat_json_object_add_ip6 (&node, "address", ip6);
4418         }
4419       else
4420         {
4421           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4422           vat_json_object_add_ip4 (&node, "address", ip4);
4423         }
4424     }
4425
4426   vec_free (status);
4427
4428   vat_json_print (vam->ofp, &node);
4429   vat_json_free (&node);
4430
4431   vam->retval = ntohl (mp->retval);
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436   vl_api_show_one_nsh_mapping_reply_t_handler
4437   (vl_api_show_one_nsh_mapping_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   i32 retval = ntohl (mp->retval);
4441
4442   if (0 <= retval)
4443     {
4444       print (vam->ofp, "%-20s%-16s",
4445              mp->is_set ? "set" : "not-set",
4446              mp->is_set ? (char *) mp->locator_set_name : "");
4447     }
4448
4449   vam->retval = retval;
4450   vam->result_ready = 1;
4451 }
4452
4453 static void
4454   vl_api_show_one_nsh_mapping_reply_t_handler_json
4455   (vl_api_show_one_nsh_mapping_reply_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458   vat_json_node_t node;
4459   u8 *status = 0;
4460
4461   status = format (0, "%s", mp->is_set ? "yes" : "no");
4462   vec_add1 (status, 0);
4463
4464   vat_json_init_object (&node);
4465   vat_json_object_add_string_copy (&node, "is_set", status);
4466   if (mp->is_set)
4467     {
4468       vat_json_object_add_string_copy (&node, "locator_set",
4469                                        mp->locator_set_name);
4470     }
4471
4472   vec_free (status);
4473
4474   vat_json_print (vam->ofp, &node);
4475   vat_json_free (&node);
4476
4477   vam->retval = ntohl (mp->retval);
4478   vam->result_ready = 1;
4479 }
4480
4481 static void
4482   vl_api_show_one_map_register_ttl_reply_t_handler
4483   (vl_api_show_one_map_register_ttl_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   i32 retval = ntohl (mp->retval);
4487
4488   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4489
4490   if (0 <= retval)
4491     {
4492       print (vam->ofp, "ttl: %u", mp->ttl);
4493     }
4494
4495   vam->retval = retval;
4496   vam->result_ready = 1;
4497 }
4498
4499 static void
4500   vl_api_show_one_map_register_ttl_reply_t_handler_json
4501   (vl_api_show_one_map_register_ttl_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   vat_json_node_t node;
4505
4506   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4507   vat_json_init_object (&node);
4508   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4509
4510   vat_json_print (vam->ofp, &node);
4511   vat_json_free (&node);
4512
4513   vam->retval = ntohl (mp->retval);
4514   vam->result_ready = 1;
4515 }
4516
4517 static void
4518 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4519 {
4520   vat_main_t *vam = &vat_main;
4521   i32 retval = ntohl (mp->retval);
4522
4523   if (0 <= retval)
4524     {
4525       print (vam->ofp, "%-20s%-16s",
4526              mp->status ? "enabled" : "disabled",
4527              mp->status ? (char *) mp->locator_set_name : "");
4528     }
4529
4530   vam->retval = retval;
4531   vam->result_ready = 1;
4532 }
4533
4534 static void
4535 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   vat_json_node_t node;
4539   u8 *status = 0;
4540
4541   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4542   vec_add1 (status, 0);
4543
4544   vat_json_init_object (&node);
4545   vat_json_object_add_string_copy (&node, "status", status);
4546   if (mp->status)
4547     {
4548       vat_json_object_add_string_copy (&node, "locator_set",
4549                                        mp->locator_set_name);
4550     }
4551
4552   vec_free (status);
4553
4554   vat_json_print (vam->ofp, &node);
4555   vat_json_free (&node);
4556
4557   vam->retval = ntohl (mp->retval);
4558   vam->result_ready = 1;
4559 }
4560
4561 static u8 *
4562 format_policer_type (u8 * s, va_list * va)
4563 {
4564   u32 i = va_arg (*va, u32);
4565
4566   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4567     s = format (s, "1r2c");
4568   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4569     s = format (s, "1r3c");
4570   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4571     s = format (s, "2r3c-2698");
4572   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4573     s = format (s, "2r3c-4115");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4575     s = format (s, "2r3c-mef5cf1");
4576   else
4577     s = format (s, "ILLEGAL");
4578   return s;
4579 }
4580
4581 static u8 *
4582 format_policer_rate_type (u8 * s, va_list * va)
4583 {
4584   u32 i = va_arg (*va, u32);
4585
4586   if (i == SSE2_QOS_RATE_KBPS)
4587     s = format (s, "kbps");
4588   else if (i == SSE2_QOS_RATE_PPS)
4589     s = format (s, "pps");
4590   else
4591     s = format (s, "ILLEGAL");
4592   return s;
4593 }
4594
4595 static u8 *
4596 format_policer_round_type (u8 * s, va_list * va)
4597 {
4598   u32 i = va_arg (*va, u32);
4599
4600   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4601     s = format (s, "closest");
4602   else if (i == SSE2_QOS_ROUND_TO_UP)
4603     s = format (s, "up");
4604   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4605     s = format (s, "down");
4606   else
4607     s = format (s, "ILLEGAL");
4608   return s;
4609 }
4610
4611 static u8 *
4612 format_policer_action_type (u8 * s, va_list * va)
4613 {
4614   u32 i = va_arg (*va, u32);
4615
4616   if (i == SSE2_QOS_ACTION_DROP)
4617     s = format (s, "drop");
4618   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4619     s = format (s, "transmit");
4620   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4621     s = format (s, "mark-and-transmit");
4622   else
4623     s = format (s, "ILLEGAL");
4624   return s;
4625 }
4626
4627 static u8 *
4628 format_dscp (u8 * s, va_list * va)
4629 {
4630   u32 i = va_arg (*va, u32);
4631   char *t = 0;
4632
4633   switch (i)
4634     {
4635 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4636       foreach_vnet_dscp
4637 #undef _
4638     default:
4639       return format (s, "ILLEGAL");
4640     }
4641   s = format (s, "%s", t);
4642   return s;
4643 }
4644
4645 static void
4646 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4647 {
4648   vat_main_t *vam = &vat_main;
4649   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4650
4651   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4652     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4653   else
4654     conform_dscp_str = format (0, "");
4655
4656   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4657     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4658   else
4659     exceed_dscp_str = format (0, "");
4660
4661   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4662     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4663   else
4664     violate_dscp_str = format (0, "");
4665
4666   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4667          "rate type %U, round type %U, %s rate, %s color-aware, "
4668          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4669          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4670          "conform action %U%s, exceed action %U%s, violate action %U%s",
4671          mp->name,
4672          format_policer_type, mp->type,
4673          ntohl (mp->cir),
4674          ntohl (mp->eir),
4675          clib_net_to_host_u64 (mp->cb),
4676          clib_net_to_host_u64 (mp->eb),
4677          format_policer_rate_type, mp->rate_type,
4678          format_policer_round_type, mp->round_type,
4679          mp->single_rate ? "single" : "dual",
4680          mp->color_aware ? "is" : "not",
4681          ntohl (mp->cir_tokens_per_period),
4682          ntohl (mp->pir_tokens_per_period),
4683          ntohl (mp->scale),
4684          ntohl (mp->current_limit),
4685          ntohl (mp->current_bucket),
4686          ntohl (mp->extended_limit),
4687          ntohl (mp->extended_bucket),
4688          clib_net_to_host_u64 (mp->last_update_time),
4689          format_policer_action_type, mp->conform_action_type,
4690          conform_dscp_str,
4691          format_policer_action_type, mp->exceed_action_type,
4692          exceed_dscp_str,
4693          format_policer_action_type, mp->violate_action_type,
4694          violate_dscp_str);
4695
4696   vec_free (conform_dscp_str);
4697   vec_free (exceed_dscp_str);
4698   vec_free (violate_dscp_str);
4699 }
4700
4701 static void vl_api_policer_details_t_handler_json
4702   (vl_api_policer_details_t * mp)
4703 {
4704   vat_main_t *vam = &vat_main;
4705   vat_json_node_t *node;
4706   u8 *rate_type_str, *round_type_str, *type_str;
4707   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4708
4709   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4710   round_type_str =
4711     format (0, "%U", format_policer_round_type, mp->round_type);
4712   type_str = format (0, "%U", format_policer_type, mp->type);
4713   conform_action_str = format (0, "%U", format_policer_action_type,
4714                                mp->conform_action_type);
4715   exceed_action_str = format (0, "%U", format_policer_action_type,
4716                               mp->exceed_action_type);
4717   violate_action_str = format (0, "%U", format_policer_action_type,
4718                                mp->violate_action_type);
4719
4720   if (VAT_JSON_ARRAY != vam->json_tree.type)
4721     {
4722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4723       vat_json_init_array (&vam->json_tree);
4724     }
4725   node = vat_json_array_add (&vam->json_tree);
4726
4727   vat_json_init_object (node);
4728   vat_json_object_add_string_copy (node, "name", mp->name);
4729   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4730   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4731   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4732   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4733   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4734   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4735   vat_json_object_add_string_copy (node, "type", type_str);
4736   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4737   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4738   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4739   vat_json_object_add_uint (node, "cir_tokens_per_period",
4740                             ntohl (mp->cir_tokens_per_period));
4741   vat_json_object_add_uint (node, "eir_tokens_per_period",
4742                             ntohl (mp->pir_tokens_per_period));
4743   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4744   vat_json_object_add_uint (node, "current_bucket",
4745                             ntohl (mp->current_bucket));
4746   vat_json_object_add_uint (node, "extended_limit",
4747                             ntohl (mp->extended_limit));
4748   vat_json_object_add_uint (node, "extended_bucket",
4749                             ntohl (mp->extended_bucket));
4750   vat_json_object_add_uint (node, "last_update_time",
4751                             ntohl (mp->last_update_time));
4752   vat_json_object_add_string_copy (node, "conform_action",
4753                                    conform_action_str);
4754   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4755     {
4756       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4757       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4758       vec_free (dscp_str);
4759     }
4760   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4761   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4762     {
4763       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4764       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4765       vec_free (dscp_str);
4766     }
4767   vat_json_object_add_string_copy (node, "violate_action",
4768                                    violate_action_str);
4769   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4770     {
4771       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4772       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4773       vec_free (dscp_str);
4774     }
4775
4776   vec_free (rate_type_str);
4777   vec_free (round_type_str);
4778   vec_free (type_str);
4779   vec_free (conform_action_str);
4780   vec_free (exceed_action_str);
4781   vec_free (violate_action_str);
4782 }
4783
4784 static void
4785 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4786                                            mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   int i, count = ntohl (mp->count);
4790
4791   if (count > 0)
4792     print (vam->ofp, "classify table ids (%d) : ", count);
4793   for (i = 0; i < count; i++)
4794     {
4795       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4796       print (vam->ofp, (i < count - 1) ? "," : "");
4797     }
4798   vam->retval = ntohl (mp->retval);
4799   vam->result_ready = 1;
4800 }
4801
4802 static void
4803   vl_api_classify_table_ids_reply_t_handler_json
4804   (vl_api_classify_table_ids_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   int i, count = ntohl (mp->count);
4808
4809   if (count > 0)
4810     {
4811       vat_json_node_t node;
4812
4813       vat_json_init_object (&node);
4814       for (i = 0; i < count; i++)
4815         {
4816           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4817         }
4818       vat_json_print (vam->ofp, &node);
4819       vat_json_free (&node);
4820     }
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 static void
4826   vl_api_classify_table_by_interface_reply_t_handler
4827   (vl_api_classify_table_by_interface_reply_t * mp)
4828 {
4829   vat_main_t *vam = &vat_main;
4830   u32 table_id;
4831
4832   table_id = ntohl (mp->l2_table_id);
4833   if (table_id != ~0)
4834     print (vam->ofp, "l2 table id : %d", table_id);
4835   else
4836     print (vam->ofp, "l2 table id : No input ACL tables configured");
4837   table_id = ntohl (mp->ip4_table_id);
4838   if (table_id != ~0)
4839     print (vam->ofp, "ip4 table id : %d", table_id);
4840   else
4841     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4842   table_id = ntohl (mp->ip6_table_id);
4843   if (table_id != ~0)
4844     print (vam->ofp, "ip6 table id : %d", table_id);
4845   else
4846     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4847   vam->retval = ntohl (mp->retval);
4848   vam->result_ready = 1;
4849 }
4850
4851 static void
4852   vl_api_classify_table_by_interface_reply_t_handler_json
4853   (vl_api_classify_table_by_interface_reply_t * mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   vat_json_node_t node;
4857
4858   vat_json_init_object (&node);
4859
4860   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4861   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4862   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4863
4864   vat_json_print (vam->ofp, &node);
4865   vat_json_free (&node);
4866
4867   vam->retval = ntohl (mp->retval);
4868   vam->result_ready = 1;
4869 }
4870
4871 static void vl_api_policer_add_del_reply_t_handler
4872   (vl_api_policer_add_del_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   i32 retval = ntohl (mp->retval);
4876   if (vam->async_mode)
4877     {
4878       vam->async_errors += (retval < 0);
4879     }
4880   else
4881     {
4882       vam->retval = retval;
4883       vam->result_ready = 1;
4884       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4885         /*
4886          * Note: this is just barely thread-safe, depends on
4887          * the main thread spinning waiting for an answer...
4888          */
4889         errmsg ("policer index %d", ntohl (mp->policer_index));
4890     }
4891 }
4892
4893 static void vl_api_policer_add_del_reply_t_handler_json
4894   (vl_api_policer_add_del_reply_t * mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897   vat_json_node_t node;
4898
4899   vat_json_init_object (&node);
4900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4901   vat_json_object_add_uint (&node, "policer_index",
4902                             ntohl (mp->policer_index));
4903
4904   vat_json_print (vam->ofp, &node);
4905   vat_json_free (&node);
4906
4907   vam->retval = ntohl (mp->retval);
4908   vam->result_ready = 1;
4909 }
4910
4911 /* Format hex dump. */
4912 u8 *
4913 format_hex_bytes (u8 * s, va_list * va)
4914 {
4915   u8 *bytes = va_arg (*va, u8 *);
4916   int n_bytes = va_arg (*va, int);
4917   uword i;
4918
4919   /* Print short or long form depending on byte count. */
4920   uword short_form = n_bytes <= 32;
4921   u32 indent = format_get_indent (s);
4922
4923   if (n_bytes == 0)
4924     return s;
4925
4926   for (i = 0; i < n_bytes; i++)
4927     {
4928       if (!short_form && (i % 32) == 0)
4929         s = format (s, "%08x: ", i);
4930       s = format (s, "%02x", bytes[i]);
4931       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4932         s = format (s, "\n%U", format_white_space, indent);
4933     }
4934
4935   return s;
4936 }
4937
4938 static void
4939 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4940                                             * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   i32 retval = ntohl (mp->retval);
4944   if (retval == 0)
4945     {
4946       print (vam->ofp, "classify table info :");
4947       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4948              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4949              ntohl (mp->miss_next_index));
4950       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4951              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4952              ntohl (mp->match_n_vectors));
4953       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4954              ntohl (mp->mask_length));
4955     }
4956   vam->retval = retval;
4957   vam->result_ready = 1;
4958 }
4959
4960 static void
4961   vl_api_classify_table_info_reply_t_handler_json
4962   (vl_api_classify_table_info_reply_t * mp)
4963 {
4964   vat_main_t *vam = &vat_main;
4965   vat_json_node_t node;
4966
4967   i32 retval = ntohl (mp->retval);
4968   if (retval == 0)
4969     {
4970       vat_json_init_object (&node);
4971
4972       vat_json_object_add_int (&node, "sessions",
4973                                ntohl (mp->active_sessions));
4974       vat_json_object_add_int (&node, "nexttbl",
4975                                ntohl (mp->next_table_index));
4976       vat_json_object_add_int (&node, "nextnode",
4977                                ntohl (mp->miss_next_index));
4978       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4979       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4980       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4981       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4982                       ntohl (mp->mask_length), 0);
4983       vat_json_object_add_string_copy (&node, "mask", s);
4984
4985       vat_json_print (vam->ofp, &node);
4986       vat_json_free (&node);
4987     }
4988   vam->retval = ntohl (mp->retval);
4989   vam->result_ready = 1;
4990 }
4991
4992 static void
4993 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4994                                            mp)
4995 {
4996   vat_main_t *vam = &vat_main;
4997
4998   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4999          ntohl (mp->hit_next_index), ntohl (mp->advance),
5000          ntohl (mp->opaque_index));
5001   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5002          ntohl (mp->match_length));
5003 }
5004
5005 static void
5006   vl_api_classify_session_details_t_handler_json
5007   (vl_api_classify_session_details_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010   vat_json_node_t *node = NULL;
5011
5012   if (VAT_JSON_ARRAY != vam->json_tree.type)
5013     {
5014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5015       vat_json_init_array (&vam->json_tree);
5016     }
5017   node = vat_json_array_add (&vam->json_tree);
5018
5019   vat_json_init_object (node);
5020   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5021   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5022   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5023   u8 *s =
5024     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5025             0);
5026   vat_json_object_add_string_copy (node, "match", s);
5027 }
5028
5029 static void vl_api_pg_create_interface_reply_t_handler
5030   (vl_api_pg_create_interface_reply_t * mp)
5031 {
5032   vat_main_t *vam = &vat_main;
5033
5034   vam->retval = ntohl (mp->retval);
5035   vam->result_ready = 1;
5036 }
5037
5038 static void vl_api_pg_create_interface_reply_t_handler_json
5039   (vl_api_pg_create_interface_reply_t * mp)
5040 {
5041   vat_main_t *vam = &vat_main;
5042   vat_json_node_t node;
5043
5044   i32 retval = ntohl (mp->retval);
5045   if (retval == 0)
5046     {
5047       vat_json_init_object (&node);
5048
5049       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5050
5051       vat_json_print (vam->ofp, &node);
5052       vat_json_free (&node);
5053     }
5054   vam->retval = ntohl (mp->retval);
5055   vam->result_ready = 1;
5056 }
5057
5058 static void vl_api_policer_classify_details_t_handler
5059   (vl_api_policer_classify_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062
5063   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5064          ntohl (mp->table_index));
5065 }
5066
5067 static void vl_api_policer_classify_details_t_handler_json
5068   (vl_api_policer_classify_details_t * mp)
5069 {
5070   vat_main_t *vam = &vat_main;
5071   vat_json_node_t *node;
5072
5073   if (VAT_JSON_ARRAY != vam->json_tree.type)
5074     {
5075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5076       vat_json_init_array (&vam->json_tree);
5077     }
5078   node = vat_json_array_add (&vam->json_tree);
5079
5080   vat_json_init_object (node);
5081   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5082   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5083 }
5084
5085 static void vl_api_flow_classify_details_t_handler
5086   (vl_api_flow_classify_details_t * mp)
5087 {
5088   vat_main_t *vam = &vat_main;
5089
5090   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5091          ntohl (mp->table_index));
5092 }
5093
5094 static void vl_api_flow_classify_details_t_handler_json
5095   (vl_api_flow_classify_details_t * mp)
5096 {
5097   vat_main_t *vam = &vat_main;
5098   vat_json_node_t *node;
5099
5100   if (VAT_JSON_ARRAY != vam->json_tree.type)
5101     {
5102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5103       vat_json_init_array (&vam->json_tree);
5104     }
5105   node = vat_json_array_add (&vam->json_tree);
5106
5107   vat_json_init_object (node);
5108   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5109   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5110 }
5111
5112 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5113 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5114 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5115 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5116 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5117 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5118 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5119 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5120 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5121 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5122
5123 /*
5124  * Generate boilerplate reply handlers, which
5125  * dig the return value out of the xxx_reply_t API message,
5126  * stick it into vam->retval, and set vam->result_ready
5127  *
5128  * Could also do this by pointing N message decode slots at
5129  * a single function, but that could break in subtle ways.
5130  */
5131
5132 #define foreach_standard_reply_retval_handler           \
5133 _(sw_interface_set_flags_reply)                         \
5134 _(sw_interface_add_del_address_reply)                   \
5135 _(sw_interface_set_rx_mode_reply)                       \
5136 _(sw_interface_set_rx_placement_reply)                  \
5137 _(sw_interface_set_table_reply)                         \
5138 _(sw_interface_set_mpls_enable_reply)                   \
5139 _(sw_interface_set_vpath_reply)                         \
5140 _(sw_interface_set_vxlan_bypass_reply)                  \
5141 _(sw_interface_set_geneve_bypass_reply)                 \
5142 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5143 _(sw_interface_set_l2_bridge_reply)                     \
5144 _(bridge_domain_add_del_reply)                          \
5145 _(sw_interface_set_l2_xconnect_reply)                   \
5146 _(l2fib_add_del_reply)                                  \
5147 _(l2fib_flush_int_reply)                                \
5148 _(l2fib_flush_bd_reply)                                 \
5149 _(ip_route_add_del_reply)                               \
5150 _(ip_table_add_del_reply)                               \
5151 _(ip_mroute_add_del_reply)                              \
5152 _(mpls_route_add_del_reply)                             \
5153 _(mpls_table_add_del_reply)                             \
5154 _(mpls_ip_bind_unbind_reply)                            \
5155 _(bier_route_add_del_reply)                             \
5156 _(bier_table_add_del_reply)                             \
5157 _(proxy_arp_add_del_reply)                              \
5158 _(proxy_arp_intfc_enable_disable_reply)                 \
5159 _(sw_interface_set_unnumbered_reply)                    \
5160 _(ip_neighbor_add_del_reply)                            \
5161 _(reset_fib_reply)                                      \
5162 _(dhcp_proxy_config_reply)                              \
5163 _(dhcp_proxy_set_vss_reply)                             \
5164 _(dhcp_client_config_reply)                             \
5165 _(set_ip_flow_hash_reply)                               \
5166 _(sw_interface_ip6_enable_disable_reply)                \
5167 _(ip6nd_proxy_add_del_reply)                            \
5168 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5169 _(sw_interface_ip6nd_ra_config_reply)                   \
5170 _(set_arp_neighbor_limit_reply)                         \
5171 _(l2_patch_add_del_reply)                               \
5172 _(sr_mpls_policy_add_reply)                             \
5173 _(sr_mpls_policy_mod_reply)                             \
5174 _(sr_mpls_policy_del_reply)                             \
5175 _(sr_policy_add_reply)                                  \
5176 _(sr_policy_mod_reply)                                  \
5177 _(sr_policy_del_reply)                                  \
5178 _(sr_localsid_add_del_reply)                            \
5179 _(sr_steering_add_del_reply)                            \
5180 _(classify_add_del_session_reply)                       \
5181 _(classify_set_interface_ip_table_reply)                \
5182 _(classify_set_interface_l2_tables_reply)               \
5183 _(l2tpv3_set_tunnel_cookies_reply)                      \
5184 _(l2tpv3_interface_enable_disable_reply)                \
5185 _(l2tpv3_set_lookup_key_reply)                          \
5186 _(l2_fib_clear_table_reply)                             \
5187 _(l2_interface_efp_filter_reply)                        \
5188 _(l2_interface_vlan_tag_rewrite_reply)                  \
5189 _(modify_vhost_user_if_reply)                           \
5190 _(delete_vhost_user_if_reply)                           \
5191 _(ip_probe_neighbor_reply)                              \
5192 _(ip_scan_neighbor_enable_disable_reply)                \
5193 _(want_ip4_arp_events_reply)                            \
5194 _(want_ip6_nd_events_reply)                             \
5195 _(want_l2_macs_events_reply)                            \
5196 _(input_acl_set_interface_reply)                        \
5197 _(ipsec_spd_add_del_reply)                              \
5198 _(ipsec_interface_add_del_spd_reply)                    \
5199 _(ipsec_spd_entry_add_del_reply)                        \
5200 _(ipsec_sad_entry_add_del_reply)                        \
5201 _(ipsec_tunnel_if_add_del_reply)                        \
5202 _(ipsec_tunnel_if_set_sa_reply)                         \
5203 _(delete_loopback_reply)                                \
5204 _(bd_ip_mac_add_del_reply)                              \
5205 _(bd_ip_mac_flush_reply)                                \
5206 _(want_interface_events_reply)                          \
5207 _(cop_interface_enable_disable_reply)                   \
5208 _(cop_whitelist_enable_disable_reply)                   \
5209 _(sw_interface_clear_stats_reply)                       \
5210 _(ioam_enable_reply)                                    \
5211 _(ioam_disable_reply)                                   \
5212 _(one_add_del_locator_reply)                            \
5213 _(one_add_del_local_eid_reply)                          \
5214 _(one_add_del_remote_mapping_reply)                     \
5215 _(one_add_del_adjacency_reply)                          \
5216 _(one_add_del_map_resolver_reply)                       \
5217 _(one_add_del_map_server_reply)                         \
5218 _(one_enable_disable_reply)                             \
5219 _(one_rloc_probe_enable_disable_reply)                  \
5220 _(one_map_register_enable_disable_reply)                \
5221 _(one_map_register_set_ttl_reply)                       \
5222 _(one_set_transport_protocol_reply)                     \
5223 _(one_map_register_fallback_threshold_reply)            \
5224 _(one_pitr_set_locator_set_reply)                       \
5225 _(one_map_request_mode_reply)                           \
5226 _(one_add_del_map_request_itr_rlocs_reply)              \
5227 _(one_eid_table_add_del_map_reply)                      \
5228 _(one_use_petr_reply)                                   \
5229 _(one_stats_enable_disable_reply)                       \
5230 _(one_add_del_l2_arp_entry_reply)                       \
5231 _(one_add_del_ndp_entry_reply)                          \
5232 _(one_stats_flush_reply)                                \
5233 _(one_enable_disable_xtr_mode_reply)                    \
5234 _(one_enable_disable_pitr_mode_reply)                   \
5235 _(one_enable_disable_petr_mode_reply)                   \
5236 _(gpe_enable_disable_reply)                             \
5237 _(gpe_set_encap_mode_reply)                             \
5238 _(gpe_add_del_iface_reply)                              \
5239 _(gpe_add_del_native_fwd_rpath_reply)                   \
5240 _(af_packet_delete_reply)                               \
5241 _(policer_classify_set_interface_reply)                 \
5242 _(netmap_create_reply)                                  \
5243 _(netmap_delete_reply)                                  \
5244 _(set_ipfix_exporter_reply)                             \
5245 _(set_ipfix_classify_stream_reply)                      \
5246 _(ipfix_classify_table_add_del_reply)                   \
5247 _(flow_classify_set_interface_reply)                    \
5248 _(sw_interface_span_enable_disable_reply)               \
5249 _(pg_capture_reply)                                     \
5250 _(pg_enable_disable_reply)                              \
5251 _(ip_source_and_port_range_check_add_del_reply)         \
5252 _(ip_source_and_port_range_check_interface_add_del_reply)\
5253 _(delete_subif_reply)                                   \
5254 _(l2_interface_pbb_tag_rewrite_reply)                   \
5255 _(set_punt_reply)                                       \
5256 _(feature_enable_disable_reply)                         \
5257 _(sw_interface_tag_add_del_reply)                       \
5258 _(hw_interface_set_mtu_reply)                           \
5259 _(p2p_ethernet_add_reply)                               \
5260 _(p2p_ethernet_del_reply)                               \
5261 _(lldp_config_reply)                                    \
5262 _(sw_interface_set_lldp_reply)                          \
5263 _(tcp_configure_src_addresses_reply)                    \
5264 _(dns_enable_disable_reply)                             \
5265 _(dns_name_server_add_del_reply)                        \
5266 _(session_rule_add_del_reply)                           \
5267 _(ip_container_proxy_add_del_reply)                     \
5268 _(output_acl_set_interface_reply)                       \
5269 _(qos_record_enable_disable_reply)
5270
5271 #define _(n)                                    \
5272     static void vl_api_##n##_t_handler          \
5273     (vl_api_##n##_t * mp)                       \
5274     {                                           \
5275         vat_main_t * vam = &vat_main;           \
5276         i32 retval = ntohl(mp->retval);         \
5277         if (vam->async_mode) {                  \
5278             vam->async_errors += (retval < 0);  \
5279         } else {                                \
5280             vam->retval = retval;               \
5281             vam->result_ready = 1;              \
5282         }                                       \
5283     }
5284 foreach_standard_reply_retval_handler;
5285 #undef _
5286
5287 #define _(n)                                    \
5288     static void vl_api_##n##_t_handler_json     \
5289     (vl_api_##n##_t * mp)                       \
5290     {                                           \
5291         vat_main_t * vam = &vat_main;           \
5292         vat_json_node_t node;                   \
5293         vat_json_init_object(&node);            \
5294         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5295         vat_json_print(vam->ofp, &node);        \
5296         vam->retval = ntohl(mp->retval);        \
5297         vam->result_ready = 1;                  \
5298     }
5299 foreach_standard_reply_retval_handler;
5300 #undef _
5301
5302 /*
5303  * Table of message reply handlers, must include boilerplate handlers
5304  * we just generated
5305  */
5306
5307 #define foreach_vpe_api_reply_msg                                       \
5308 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5309 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5310 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5311 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5312 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5313 _(CLI_REPLY, cli_reply)                                                 \
5314 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5315 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5316   sw_interface_add_del_address_reply)                                   \
5317 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5318 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5319 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5320 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5321 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5322 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5323 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5324 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5325 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5326 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5327   sw_interface_set_l2_xconnect_reply)                                   \
5328 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5329   sw_interface_set_l2_bridge_reply)                                     \
5330 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5331 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5332 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5333 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5334 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5335 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5336 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5337 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5338 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5339 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5340 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5341 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5342 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5343 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5344 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5345 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5346 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5347 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5348 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5349 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5350 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5351 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5352 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5353 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5354 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5355 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5356 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5357 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5358 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5359 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5360   proxy_arp_intfc_enable_disable_reply)                                 \
5361 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5362 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5363   sw_interface_set_unnumbered_reply)                                    \
5364 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5365 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5366 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5367 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5368 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5369 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5370 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5371 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5372 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5373 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5374   sw_interface_ip6_enable_disable_reply)                                \
5375 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5376 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5377 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5378   sw_interface_ip6nd_ra_prefix_reply)                                   \
5379 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5380   sw_interface_ip6nd_ra_config_reply)                                   \
5381 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5382 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5383 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5384 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5385 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5386 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5387 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5388 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5389 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5390 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5391 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5392 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5393 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5394 classify_set_interface_ip_table_reply)                                  \
5395 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5396   classify_set_interface_l2_tables_reply)                               \
5397 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5398 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5399 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5400 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5401 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5402   l2tpv3_interface_enable_disable_reply)                                \
5403 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5404 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5405 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5406 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5407 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5408 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5409 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5410 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5411 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5412 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5413 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5414 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5415 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5416 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5417 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5418 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5419 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5420 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5421 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5422 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5423 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5424 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5425 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5426 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5427 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5428 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5429 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5430 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5431 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5432 _(L2_MACS_EVENT, l2_macs_event)                                         \
5433 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5434 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5435 _(IP_DETAILS, ip_details)                                               \
5436 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5437 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5438 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5439 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5440 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5441 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5442 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5443 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5444 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5445 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5446 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5447 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5448 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5449 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5450 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5451 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5452 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5453 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5454 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5455 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5456 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5457 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5458 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5459 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5460 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5461 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5462 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5463 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5464 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5465   one_map_register_enable_disable_reply)                                \
5466 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5467 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5468 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5469 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5470   one_map_register_fallback_threshold_reply)                            \
5471 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5472   one_rloc_probe_enable_disable_reply)                                  \
5473 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5474 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5475 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5476 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5477 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5478 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5479 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5480 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5481 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5482 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5483 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5484 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5485 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5486 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5487 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5488 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5489   show_one_stats_enable_disable_reply)                                  \
5490 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5491 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5492 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5493 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5494 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5495 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5496 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5497 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5498   one_enable_disable_pitr_mode_reply)                                   \
5499 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5500   one_enable_disable_petr_mode_reply)                                   \
5501 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5502 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5503 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5504 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5505 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5506 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5507 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5508 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5509 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5510 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5511 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5512 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5513   gpe_add_del_native_fwd_rpath_reply)                                   \
5514 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5515   gpe_fwd_entry_path_details)                                           \
5516 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5517 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5518   one_add_del_map_request_itr_rlocs_reply)                              \
5519 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5520   one_get_map_request_itr_rlocs_reply)                                  \
5521 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5522 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5523 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5524 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5525 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5526 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5527   show_one_map_register_state_reply)                                    \
5528 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5529 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5530   show_one_map_register_fallback_threshold_reply)                       \
5531 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5532 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5533 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5534 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5535 _(POLICER_DETAILS, policer_details)                                     \
5536 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5537 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5538 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5539 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5540 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5541 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5542 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5543 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5544 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5545 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5546 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5547 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5548 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5549 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5550 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5551 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5552 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5553 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5554 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5555 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5556 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5557 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5558 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5559 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5560 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5561 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5562  ip_source_and_port_range_check_add_del_reply)                          \
5563 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5564  ip_source_and_port_range_check_interface_add_del_reply)                \
5565 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5566 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5567 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5568 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5569 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5570 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5571 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5572 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5573 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5574 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5575 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5576 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5577 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5578 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5579 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5580 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5581 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5582 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5583 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5584 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5585 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5586 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5587 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5588 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5589 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5590 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5591
5592 #define foreach_standalone_reply_msg                                    \
5593 _(SW_INTERFACE_EVENT, sw_interface_event)
5594
5595 typedef struct
5596 {
5597   u8 *name;
5598   u32 value;
5599 } name_sort_t;
5600
5601 #define STR_VTR_OP_CASE(op)     \
5602     case L2_VTR_ ## op:         \
5603         return "" # op;
5604
5605 static const char *
5606 str_vtr_op (u32 vtr_op)
5607 {
5608   switch (vtr_op)
5609     {
5610       STR_VTR_OP_CASE (DISABLED);
5611       STR_VTR_OP_CASE (PUSH_1);
5612       STR_VTR_OP_CASE (PUSH_2);
5613       STR_VTR_OP_CASE (POP_1);
5614       STR_VTR_OP_CASE (POP_2);
5615       STR_VTR_OP_CASE (TRANSLATE_1_1);
5616       STR_VTR_OP_CASE (TRANSLATE_1_2);
5617       STR_VTR_OP_CASE (TRANSLATE_2_1);
5618       STR_VTR_OP_CASE (TRANSLATE_2_2);
5619     }
5620
5621   return "UNKNOWN";
5622 }
5623
5624 static int
5625 dump_sub_interface_table (vat_main_t * vam)
5626 {
5627   const sw_interface_subif_t *sub = NULL;
5628
5629   if (vam->json_output)
5630     {
5631       clib_warning
5632         ("JSON output supported only for VPE API calls and dump_stats_table");
5633       return -99;
5634     }
5635
5636   print (vam->ofp,
5637          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5638          "Interface", "sw_if_index",
5639          "sub id", "dot1ad", "tags", "outer id",
5640          "inner id", "exact", "default", "outer any", "inner any");
5641
5642   vec_foreach (sub, vam->sw_if_subif_table)
5643   {
5644     print (vam->ofp,
5645            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5646            sub->interface_name,
5647            sub->sw_if_index,
5648            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5649            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5650            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5651            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5652     if (sub->vtr_op != L2_VTR_DISABLED)
5653       {
5654         print (vam->ofp,
5655                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5656                "tag1: %d tag2: %d ]",
5657                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5658                sub->vtr_tag1, sub->vtr_tag2);
5659       }
5660   }
5661
5662   return 0;
5663 }
5664
5665 static int
5666 name_sort_cmp (void *a1, void *a2)
5667 {
5668   name_sort_t *n1 = a1;
5669   name_sort_t *n2 = a2;
5670
5671   return strcmp ((char *) n1->name, (char *) n2->name);
5672 }
5673
5674 static int
5675 dump_interface_table (vat_main_t * vam)
5676 {
5677   hash_pair_t *p;
5678   name_sort_t *nses = 0, *ns;
5679
5680   if (vam->json_output)
5681     {
5682       clib_warning
5683         ("JSON output supported only for VPE API calls and dump_stats_table");
5684       return -99;
5685     }
5686
5687   /* *INDENT-OFF* */
5688   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5689   ({
5690     vec_add2 (nses, ns, 1);
5691     ns->name = (u8 *)(p->key);
5692     ns->value = (u32) p->value[0];
5693   }));
5694   /* *INDENT-ON* */
5695
5696   vec_sort_with_function (nses, name_sort_cmp);
5697
5698   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5699   vec_foreach (ns, nses)
5700   {
5701     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5702   }
5703   vec_free (nses);
5704   return 0;
5705 }
5706
5707 static int
5708 dump_ip_table (vat_main_t * vam, int is_ipv6)
5709 {
5710   const ip_details_t *det = NULL;
5711   const ip_address_details_t *address = NULL;
5712   u32 i = ~0;
5713
5714   print (vam->ofp, "%-12s", "sw_if_index");
5715
5716   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5717   {
5718     i++;
5719     if (!det->present)
5720       {
5721         continue;
5722       }
5723     print (vam->ofp, "%-12d", i);
5724     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5725     if (!det->addr)
5726       {
5727         continue;
5728       }
5729     vec_foreach (address, det->addr)
5730     {
5731       print (vam->ofp,
5732              "            %-30U%-13d",
5733              is_ipv6 ? format_ip6_address : format_ip4_address,
5734              address->ip, address->prefix_length);
5735     }
5736   }
5737
5738   return 0;
5739 }
5740
5741 static int
5742 dump_ipv4_table (vat_main_t * vam)
5743 {
5744   if (vam->json_output)
5745     {
5746       clib_warning
5747         ("JSON output supported only for VPE API calls and dump_stats_table");
5748       return -99;
5749     }
5750
5751   return dump_ip_table (vam, 0);
5752 }
5753
5754 static int
5755 dump_ipv6_table (vat_main_t * vam)
5756 {
5757   if (vam->json_output)
5758     {
5759       clib_warning
5760         ("JSON output supported only for VPE API calls and dump_stats_table");
5761       return -99;
5762     }
5763
5764   return dump_ip_table (vam, 1);
5765 }
5766
5767 /*
5768  * Pass CLI buffers directly in the CLI_INBAND API message,
5769  * instead of an additional shared memory area.
5770  */
5771 static int
5772 exec_inband (vat_main_t * vam)
5773 {
5774   vl_api_cli_inband_t *mp;
5775   unformat_input_t *i = vam->input;
5776   int ret;
5777
5778   if (vec_len (i->buffer) == 0)
5779     return -1;
5780
5781   if (vam->exec_mode == 0 && unformat (i, "mode"))
5782     {
5783       vam->exec_mode = 1;
5784       return 0;
5785     }
5786   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5787     {
5788       vam->exec_mode = 0;
5789       return 0;
5790     }
5791
5792   /*
5793    * In order for the CLI command to work, it
5794    * must be a vector ending in \n, not a C-string ending
5795    * in \n\0.
5796    */
5797   u32 len = vec_len (vam->input->buffer);
5798   M2 (CLI_INBAND, mp, len);
5799   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5800
5801   S (mp);
5802   W (ret);
5803   /* json responses may or may not include a useful reply... */
5804   if (vec_len (vam->cmd_reply))
5805     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5806   return ret;
5807 }
5808
5809 int
5810 exec (vat_main_t * vam)
5811 {
5812   return exec_inband (vam);
5813 }
5814
5815 static int
5816 api_create_loopback (vat_main_t * vam)
5817 {
5818   unformat_input_t *i = vam->input;
5819   vl_api_create_loopback_t *mp;
5820   vl_api_create_loopback_instance_t *mp_lbi;
5821   u8 mac_address[6];
5822   u8 mac_set = 0;
5823   u8 is_specified = 0;
5824   u32 user_instance = 0;
5825   int ret;
5826
5827   clib_memset (mac_address, 0, sizeof (mac_address));
5828
5829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5830     {
5831       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5832         mac_set = 1;
5833       if (unformat (i, "instance %d", &user_instance))
5834         is_specified = 1;
5835       else
5836         break;
5837     }
5838
5839   if (is_specified)
5840     {
5841       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5842       mp_lbi->is_specified = is_specified;
5843       if (is_specified)
5844         mp_lbi->user_instance = htonl (user_instance);
5845       if (mac_set)
5846         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5847       S (mp_lbi);
5848     }
5849   else
5850     {
5851       /* Construct the API message */
5852       M (CREATE_LOOPBACK, mp);
5853       if (mac_set)
5854         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5855       S (mp);
5856     }
5857
5858   W (ret);
5859   return ret;
5860 }
5861
5862 static int
5863 api_delete_loopback (vat_main_t * vam)
5864 {
5865   unformat_input_t *i = vam->input;
5866   vl_api_delete_loopback_t *mp;
5867   u32 sw_if_index = ~0;
5868   int ret;
5869
5870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5871     {
5872       if (unformat (i, "sw_if_index %d", &sw_if_index))
5873         ;
5874       else
5875         break;
5876     }
5877
5878   if (sw_if_index == ~0)
5879     {
5880       errmsg ("missing sw_if_index");
5881       return -99;
5882     }
5883
5884   /* Construct the API message */
5885   M (DELETE_LOOPBACK, mp);
5886   mp->sw_if_index = ntohl (sw_if_index);
5887
5888   S (mp);
5889   W (ret);
5890   return ret;
5891 }
5892
5893 static int
5894 api_want_interface_events (vat_main_t * vam)
5895 {
5896   unformat_input_t *i = vam->input;
5897   vl_api_want_interface_events_t *mp;
5898   int enable = -1;
5899   int ret;
5900
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "enable"))
5904         enable = 1;
5905       else if (unformat (i, "disable"))
5906         enable = 0;
5907       else
5908         break;
5909     }
5910
5911   if (enable == -1)
5912     {
5913       errmsg ("missing enable|disable");
5914       return -99;
5915     }
5916
5917   M (WANT_INTERFACE_EVENTS, mp);
5918   mp->enable_disable = enable;
5919
5920   vam->interface_event_display = enable;
5921
5922   S (mp);
5923   W (ret);
5924   return ret;
5925 }
5926
5927
5928 /* Note: non-static, called once to set up the initial intfc table */
5929 int
5930 api_sw_interface_dump (vat_main_t * vam)
5931 {
5932   vl_api_sw_interface_dump_t *mp;
5933   vl_api_control_ping_t *mp_ping;
5934   hash_pair_t *p;
5935   name_sort_t *nses = 0, *ns;
5936   sw_interface_subif_t *sub = NULL;
5937   int ret;
5938
5939   /* Toss the old name table */
5940   /* *INDENT-OFF* */
5941   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5942   ({
5943     vec_add2 (nses, ns, 1);
5944     ns->name = (u8 *)(p->key);
5945     ns->value = (u32) p->value[0];
5946   }));
5947   /* *INDENT-ON* */
5948
5949   hash_free (vam->sw_if_index_by_interface_name);
5950
5951   vec_foreach (ns, nses) vec_free (ns->name);
5952
5953   vec_free (nses);
5954
5955   vec_foreach (sub, vam->sw_if_subif_table)
5956   {
5957     vec_free (sub->interface_name);
5958   }
5959   vec_free (vam->sw_if_subif_table);
5960
5961   /* recreate the interface name hash table */
5962   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5963
5964   /*
5965    * Ask for all interface names. Otherwise, the epic catalog of
5966    * name filters becomes ridiculously long, and vat ends up needing
5967    * to be taught about new interface types.
5968    */
5969   M (SW_INTERFACE_DUMP, mp);
5970   S (mp);
5971
5972   /* Use a control ping for synchronization */
5973   MPING (CONTROL_PING, mp_ping);
5974   S (mp_ping);
5975
5976   W (ret);
5977   return ret;
5978 }
5979
5980 static int
5981 api_sw_interface_set_flags (vat_main_t * vam)
5982 {
5983   unformat_input_t *i = vam->input;
5984   vl_api_sw_interface_set_flags_t *mp;
5985   u32 sw_if_index;
5986   u8 sw_if_index_set = 0;
5987   u8 admin_up = 0;
5988   int ret;
5989
5990   /* Parse args required to build the message */
5991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5992     {
5993       if (unformat (i, "admin-up"))
5994         admin_up = 1;
5995       else if (unformat (i, "admin-down"))
5996         admin_up = 0;
5997       else
5998         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5999         sw_if_index_set = 1;
6000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6001         sw_if_index_set = 1;
6002       else
6003         break;
6004     }
6005
6006   if (sw_if_index_set == 0)
6007     {
6008       errmsg ("missing interface name or sw_if_index");
6009       return -99;
6010     }
6011
6012   /* Construct the API message */
6013   M (SW_INTERFACE_SET_FLAGS, mp);
6014   mp->sw_if_index = ntohl (sw_if_index);
6015   mp->admin_up_down = admin_up;
6016
6017   /* send it... */
6018   S (mp);
6019
6020   /* Wait for a reply, return the good/bad news... */
6021   W (ret);
6022   return ret;
6023 }
6024
6025 static int
6026 api_sw_interface_set_rx_mode (vat_main_t * vam)
6027 {
6028   unformat_input_t *i = vam->input;
6029   vl_api_sw_interface_set_rx_mode_t *mp;
6030   u32 sw_if_index;
6031   u8 sw_if_index_set = 0;
6032   int ret;
6033   u8 queue_id_valid = 0;
6034   u32 queue_id;
6035   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6036
6037   /* Parse args required to build the message */
6038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039     {
6040       if (unformat (i, "queue %d", &queue_id))
6041         queue_id_valid = 1;
6042       else if (unformat (i, "polling"))
6043         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6044       else if (unformat (i, "interrupt"))
6045         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6046       else if (unformat (i, "adaptive"))
6047         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6048       else
6049         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6050         sw_if_index_set = 1;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         sw_if_index_set = 1;
6053       else
6054         break;
6055     }
6056
6057   if (sw_if_index_set == 0)
6058     {
6059       errmsg ("missing interface name or sw_if_index");
6060       return -99;
6061     }
6062   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6063     {
6064       errmsg ("missing rx-mode");
6065       return -99;
6066     }
6067
6068   /* Construct the API message */
6069   M (SW_INTERFACE_SET_RX_MODE, mp);
6070   mp->sw_if_index = ntohl (sw_if_index);
6071   mp->mode = mode;
6072   mp->queue_id_valid = queue_id_valid;
6073   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6074
6075   /* send it... */
6076   S (mp);
6077
6078   /* Wait for a reply, return the good/bad news... */
6079   W (ret);
6080   return ret;
6081 }
6082
6083 static int
6084 api_sw_interface_set_rx_placement (vat_main_t * vam)
6085 {
6086   unformat_input_t *i = vam->input;
6087   vl_api_sw_interface_set_rx_placement_t *mp;
6088   u32 sw_if_index;
6089   u8 sw_if_index_set = 0;
6090   int ret;
6091   u8 is_main = 0;
6092   u32 queue_id, thread_index;
6093
6094   /* Parse args required to build the message */
6095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6096     {
6097       if (unformat (i, "queue %d", &queue_id))
6098         ;
6099       else if (unformat (i, "main"))
6100         is_main = 1;
6101       else if (unformat (i, "worker %d", &thread_index))
6102         ;
6103       else
6104         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6105         sw_if_index_set = 1;
6106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6107         sw_if_index_set = 1;
6108       else
6109         break;
6110     }
6111
6112   if (sw_if_index_set == 0)
6113     {
6114       errmsg ("missing interface name or sw_if_index");
6115       return -99;
6116     }
6117
6118   if (is_main)
6119     thread_index = 0;
6120   /* Construct the API message */
6121   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6122   mp->sw_if_index = ntohl (sw_if_index);
6123   mp->worker_id = ntohl (thread_index);
6124   mp->queue_id = ntohl (queue_id);
6125   mp->is_main = is_main;
6126
6127   /* send it... */
6128   S (mp);
6129   /* Wait for a reply, return the good/bad news... */
6130   W (ret);
6131   return ret;
6132 }
6133
6134 static void vl_api_sw_interface_rx_placement_details_t_handler
6135   (vl_api_sw_interface_rx_placement_details_t * mp)
6136 {
6137   vat_main_t *vam = &vat_main;
6138   u32 worker_id = ntohl (mp->worker_id);
6139
6140   print (vam->ofp,
6141          "\n%-11d %-11s %-6d %-5d %-9s",
6142          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6143          worker_id, ntohl (mp->queue_id),
6144          (mp->mode ==
6145           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6146 }
6147
6148 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6149   (vl_api_sw_interface_rx_placement_details_t * mp)
6150 {
6151   vat_main_t *vam = &vat_main;
6152   vat_json_node_t *node = NULL;
6153
6154   if (VAT_JSON_ARRAY != vam->json_tree.type)
6155     {
6156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6157       vat_json_init_array (&vam->json_tree);
6158     }
6159   node = vat_json_array_add (&vam->json_tree);
6160
6161   vat_json_init_object (node);
6162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6163   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6164   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6165   vat_json_object_add_uint (node, "mode", mp->mode);
6166 }
6167
6168 static int
6169 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6170 {
6171   unformat_input_t *i = vam->input;
6172   vl_api_sw_interface_rx_placement_dump_t *mp;
6173   vl_api_control_ping_t *mp_ping;
6174   int ret;
6175   u32 sw_if_index;
6176   u8 sw_if_index_set = 0;
6177
6178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6179     {
6180       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6181         sw_if_index_set++;
6182       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6183         sw_if_index_set++;
6184       else
6185         break;
6186     }
6187
6188   print (vam->ofp,
6189          "\n%-11s %-11s %-6s %-5s %-4s",
6190          "sw_if_index", "main/worker", "thread", "queue", "mode");
6191
6192   /* Dump Interface rx placement */
6193   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6194
6195   if (sw_if_index_set)
6196     mp->sw_if_index = htonl (sw_if_index);
6197   else
6198     mp->sw_if_index = ~0;
6199
6200   S (mp);
6201
6202   /* Use a control ping for synchronization */
6203   MPING (CONTROL_PING, mp_ping);
6204   S (mp_ping);
6205
6206   W (ret);
6207   return ret;
6208 }
6209
6210 static int
6211 api_sw_interface_clear_stats (vat_main_t * vam)
6212 {
6213   unformat_input_t *i = vam->input;
6214   vl_api_sw_interface_clear_stats_t *mp;
6215   u32 sw_if_index;
6216   u8 sw_if_index_set = 0;
6217   int ret;
6218
6219   /* Parse args required to build the message */
6220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6221     {
6222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6223         sw_if_index_set = 1;
6224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6225         sw_if_index_set = 1;
6226       else
6227         break;
6228     }
6229
6230   /* Construct the API message */
6231   M (SW_INTERFACE_CLEAR_STATS, mp);
6232
6233   if (sw_if_index_set == 1)
6234     mp->sw_if_index = ntohl (sw_if_index);
6235   else
6236     mp->sw_if_index = ~0;
6237
6238   /* send it... */
6239   S (mp);
6240
6241   /* Wait for a reply, return the good/bad news... */
6242   W (ret);
6243   return ret;
6244 }
6245
6246 static int
6247 api_sw_interface_add_del_address (vat_main_t * vam)
6248 {
6249   unformat_input_t *i = vam->input;
6250   vl_api_sw_interface_add_del_address_t *mp;
6251   u32 sw_if_index;
6252   u8 sw_if_index_set = 0;
6253   u8 is_add = 1, del_all = 0;
6254   u32 address_length = 0;
6255   u8 v4_address_set = 0;
6256   u8 v6_address_set = 0;
6257   ip4_address_t v4address;
6258   ip6_address_t v6address;
6259   int ret;
6260
6261   /* Parse args required to build the message */
6262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6263     {
6264       if (unformat (i, "del-all"))
6265         del_all = 1;
6266       else if (unformat (i, "del"))
6267         is_add = 0;
6268       else
6269         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6270         sw_if_index_set = 1;
6271       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6272         sw_if_index_set = 1;
6273       else if (unformat (i, "%U/%d",
6274                          unformat_ip4_address, &v4address, &address_length))
6275         v4_address_set = 1;
6276       else if (unformat (i, "%U/%d",
6277                          unformat_ip6_address, &v6address, &address_length))
6278         v6_address_set = 1;
6279       else
6280         break;
6281     }
6282
6283   if (sw_if_index_set == 0)
6284     {
6285       errmsg ("missing interface name or sw_if_index");
6286       return -99;
6287     }
6288   if (v4_address_set && v6_address_set)
6289     {
6290       errmsg ("both v4 and v6 addresses set");
6291       return -99;
6292     }
6293   if (!v4_address_set && !v6_address_set && !del_all)
6294     {
6295       errmsg ("no addresses set");
6296       return -99;
6297     }
6298
6299   /* Construct the API message */
6300   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6301
6302   mp->sw_if_index = ntohl (sw_if_index);
6303   mp->is_add = is_add;
6304   mp->del_all = del_all;
6305   if (v6_address_set)
6306     {
6307       mp->is_ipv6 = 1;
6308       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6309     }
6310   else
6311     {
6312       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6313     }
6314   mp->address_length = address_length;
6315
6316   /* send it... */
6317   S (mp);
6318
6319   /* Wait for a reply, return good/bad news  */
6320   W (ret);
6321   return ret;
6322 }
6323
6324 static int
6325 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6326 {
6327   unformat_input_t *i = vam->input;
6328   vl_api_sw_interface_set_mpls_enable_t *mp;
6329   u32 sw_if_index;
6330   u8 sw_if_index_set = 0;
6331   u8 enable = 1;
6332   int ret;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6338         sw_if_index_set = 1;
6339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "disable"))
6342         enable = 0;
6343       else if (unformat (i, "dis"))
6344         enable = 0;
6345       else
6346         break;
6347     }
6348
6349   if (sw_if_index_set == 0)
6350     {
6351       errmsg ("missing interface name or sw_if_index");
6352       return -99;
6353     }
6354
6355   /* Construct the API message */
6356   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6357
6358   mp->sw_if_index = ntohl (sw_if_index);
6359   mp->enable = enable;
6360
6361   /* send it... */
6362   S (mp);
6363
6364   /* Wait for a reply... */
6365   W (ret);
6366   return ret;
6367 }
6368
6369 static int
6370 api_sw_interface_set_table (vat_main_t * vam)
6371 {
6372   unformat_input_t *i = vam->input;
6373   vl_api_sw_interface_set_table_t *mp;
6374   u32 sw_if_index, vrf_id = 0;
6375   u8 sw_if_index_set = 0;
6376   u8 is_ipv6 = 0;
6377   int ret;
6378
6379   /* Parse args required to build the message */
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383         sw_if_index_set = 1;
6384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385         sw_if_index_set = 1;
6386       else if (unformat (i, "vrf %d", &vrf_id))
6387         ;
6388       else if (unformat (i, "ipv6"))
6389         is_ipv6 = 1;
6390       else
6391         break;
6392     }
6393
6394   if (sw_if_index_set == 0)
6395     {
6396       errmsg ("missing interface name or sw_if_index");
6397       return -99;
6398     }
6399
6400   /* Construct the API message */
6401   M (SW_INTERFACE_SET_TABLE, mp);
6402
6403   mp->sw_if_index = ntohl (sw_if_index);
6404   mp->is_ipv6 = is_ipv6;
6405   mp->vrf_id = ntohl (vrf_id);
6406
6407   /* send it... */
6408   S (mp);
6409
6410   /* Wait for a reply... */
6411   W (ret);
6412   return ret;
6413 }
6414
6415 static void vl_api_sw_interface_get_table_reply_t_handler
6416   (vl_api_sw_interface_get_table_reply_t * mp)
6417 {
6418   vat_main_t *vam = &vat_main;
6419
6420   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6421
6422   vam->retval = ntohl (mp->retval);
6423   vam->result_ready = 1;
6424
6425 }
6426
6427 static void vl_api_sw_interface_get_table_reply_t_handler_json
6428   (vl_api_sw_interface_get_table_reply_t * mp)
6429 {
6430   vat_main_t *vam = &vat_main;
6431   vat_json_node_t node;
6432
6433   vat_json_init_object (&node);
6434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6435   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6436
6437   vat_json_print (vam->ofp, &node);
6438   vat_json_free (&node);
6439
6440   vam->retval = ntohl (mp->retval);
6441   vam->result_ready = 1;
6442 }
6443
6444 static int
6445 api_sw_interface_get_table (vat_main_t * vam)
6446 {
6447   unformat_input_t *i = vam->input;
6448   vl_api_sw_interface_get_table_t *mp;
6449   u32 sw_if_index;
6450   u8 sw_if_index_set = 0;
6451   u8 is_ipv6 = 0;
6452   int ret;
6453
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6457         sw_if_index_set = 1;
6458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6459         sw_if_index_set = 1;
6460       else if (unformat (i, "ipv6"))
6461         is_ipv6 = 1;
6462       else
6463         break;
6464     }
6465
6466   if (sw_if_index_set == 0)
6467     {
6468       errmsg ("missing interface name or sw_if_index");
6469       return -99;
6470     }
6471
6472   M (SW_INTERFACE_GET_TABLE, mp);
6473   mp->sw_if_index = htonl (sw_if_index);
6474   mp->is_ipv6 = is_ipv6;
6475
6476   S (mp);
6477   W (ret);
6478   return ret;
6479 }
6480
6481 static int
6482 api_sw_interface_set_vpath (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_sw_interface_set_vpath_t *mp;
6486   u32 sw_if_index = 0;
6487   u8 sw_if_index_set = 0;
6488   u8 is_enable = 0;
6489   int ret;
6490
6491   /* Parse args required to build the message */
6492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6493     {
6494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6495         sw_if_index_set = 1;
6496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6497         sw_if_index_set = 1;
6498       else if (unformat (i, "enable"))
6499         is_enable = 1;
6500       else if (unformat (i, "disable"))
6501         is_enable = 0;
6502       else
6503         break;
6504     }
6505
6506   if (sw_if_index_set == 0)
6507     {
6508       errmsg ("missing interface name or sw_if_index");
6509       return -99;
6510     }
6511
6512   /* Construct the API message */
6513   M (SW_INTERFACE_SET_VPATH, mp);
6514
6515   mp->sw_if_index = ntohl (sw_if_index);
6516   mp->enable = is_enable;
6517
6518   /* send it... */
6519   S (mp);
6520
6521   /* Wait for a reply... */
6522   W (ret);
6523   return ret;
6524 }
6525
6526 static int
6527 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6528 {
6529   unformat_input_t *i = vam->input;
6530   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6531   u32 sw_if_index = 0;
6532   u8 sw_if_index_set = 0;
6533   u8 is_enable = 1;
6534   u8 is_ipv6 = 0;
6535   int ret;
6536
6537   /* Parse args required to build the message */
6538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6539     {
6540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6541         sw_if_index_set = 1;
6542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6543         sw_if_index_set = 1;
6544       else if (unformat (i, "enable"))
6545         is_enable = 1;
6546       else if (unformat (i, "disable"))
6547         is_enable = 0;
6548       else if (unformat (i, "ip4"))
6549         is_ipv6 = 0;
6550       else if (unformat (i, "ip6"))
6551         is_ipv6 = 1;
6552       else
6553         break;
6554     }
6555
6556   if (sw_if_index_set == 0)
6557     {
6558       errmsg ("missing interface name or sw_if_index");
6559       return -99;
6560     }
6561
6562   /* Construct the API message */
6563   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6564
6565   mp->sw_if_index = ntohl (sw_if_index);
6566   mp->enable = is_enable;
6567   mp->is_ipv6 = is_ipv6;
6568
6569   /* send it... */
6570   S (mp);
6571
6572   /* Wait for a reply... */
6573   W (ret);
6574   return ret;
6575 }
6576
6577 static int
6578 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6579 {
6580   unformat_input_t *i = vam->input;
6581   vl_api_sw_interface_set_geneve_bypass_t *mp;
6582   u32 sw_if_index = 0;
6583   u8 sw_if_index_set = 0;
6584   u8 is_enable = 1;
6585   u8 is_ipv6 = 0;
6586   int ret;
6587
6588   /* Parse args required to build the message */
6589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6590     {
6591       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6592         sw_if_index_set = 1;
6593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "enable"))
6596         is_enable = 1;
6597       else if (unformat (i, "disable"))
6598         is_enable = 0;
6599       else if (unformat (i, "ip4"))
6600         is_ipv6 = 0;
6601       else if (unformat (i, "ip6"))
6602         is_ipv6 = 1;
6603       else
6604         break;
6605     }
6606
6607   if (sw_if_index_set == 0)
6608     {
6609       errmsg ("missing interface name or sw_if_index");
6610       return -99;
6611     }
6612
6613   /* Construct the API message */
6614   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6615
6616   mp->sw_if_index = ntohl (sw_if_index);
6617   mp->enable = is_enable;
6618   mp->is_ipv6 = is_ipv6;
6619
6620   /* send it... */
6621   S (mp);
6622
6623   /* Wait for a reply... */
6624   W (ret);
6625   return ret;
6626 }
6627
6628 static int
6629 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6630 {
6631   unformat_input_t *i = vam->input;
6632   vl_api_sw_interface_set_l2_xconnect_t *mp;
6633   u32 rx_sw_if_index;
6634   u8 rx_sw_if_index_set = 0;
6635   u32 tx_sw_if_index;
6636   u8 tx_sw_if_index_set = 0;
6637   u8 enable = 1;
6638   int ret;
6639
6640   /* Parse args required to build the message */
6641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6642     {
6643       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6644         rx_sw_if_index_set = 1;
6645       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6646         tx_sw_if_index_set = 1;
6647       else if (unformat (i, "rx"))
6648         {
6649           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650             {
6651               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6652                             &rx_sw_if_index))
6653                 rx_sw_if_index_set = 1;
6654             }
6655           else
6656             break;
6657         }
6658       else if (unformat (i, "tx"))
6659         {
6660           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6661             {
6662               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6663                             &tx_sw_if_index))
6664                 tx_sw_if_index_set = 1;
6665             }
6666           else
6667             break;
6668         }
6669       else if (unformat (i, "enable"))
6670         enable = 1;
6671       else if (unformat (i, "disable"))
6672         enable = 0;
6673       else
6674         break;
6675     }
6676
6677   if (rx_sw_if_index_set == 0)
6678     {
6679       errmsg ("missing rx interface name or rx_sw_if_index");
6680       return -99;
6681     }
6682
6683   if (enable && (tx_sw_if_index_set == 0))
6684     {
6685       errmsg ("missing tx interface name or tx_sw_if_index");
6686       return -99;
6687     }
6688
6689   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6690
6691   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6692   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6693   mp->enable = enable;
6694
6695   S (mp);
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_set_l2_bridge_t *mp;
6705   vl_api_l2_port_type_t port_type;
6706   u32 rx_sw_if_index;
6707   u8 rx_sw_if_index_set = 0;
6708   u32 bd_id;
6709   u8 bd_id_set = 0;
6710   u32 shg = 0;
6711   u8 enable = 1;
6712   int ret;
6713
6714   port_type = L2_API_PORT_TYPE_NORMAL;
6715
6716   /* Parse args required to build the message */
6717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6718     {
6719       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6720         rx_sw_if_index_set = 1;
6721       else if (unformat (i, "bd_id %d", &bd_id))
6722         bd_id_set = 1;
6723       else
6724         if (unformat
6725             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6726         rx_sw_if_index_set = 1;
6727       else if (unformat (i, "shg %d", &shg))
6728         ;
6729       else if (unformat (i, "bvi"))
6730         port_type = L2_API_PORT_TYPE_BVI;
6731       else if (unformat (i, "uu-fwd"))
6732         port_type = L2_API_PORT_TYPE_UU_FWD;
6733       else if (unformat (i, "enable"))
6734         enable = 1;
6735       else if (unformat (i, "disable"))
6736         enable = 0;
6737       else
6738         break;
6739     }
6740
6741   if (rx_sw_if_index_set == 0)
6742     {
6743       errmsg ("missing rx interface name or sw_if_index");
6744       return -99;
6745     }
6746
6747   if (enable && (bd_id_set == 0))
6748     {
6749       errmsg ("missing bridge domain");
6750       return -99;
6751     }
6752
6753   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6754
6755   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6756   mp->bd_id = ntohl (bd_id);
6757   mp->shg = (u8) shg;
6758   mp->port_type = ntohl (port_type);
6759   mp->enable = enable;
6760
6761   S (mp);
6762   W (ret);
6763   return ret;
6764 }
6765
6766 static int
6767 api_bridge_domain_dump (vat_main_t * vam)
6768 {
6769   unformat_input_t *i = vam->input;
6770   vl_api_bridge_domain_dump_t *mp;
6771   vl_api_control_ping_t *mp_ping;
6772   u32 bd_id = ~0;
6773   int ret;
6774
6775   /* Parse args required to build the message */
6776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6777     {
6778       if (unformat (i, "bd_id %d", &bd_id))
6779         ;
6780       else
6781         break;
6782     }
6783
6784   M (BRIDGE_DOMAIN_DUMP, mp);
6785   mp->bd_id = ntohl (bd_id);
6786   S (mp);
6787
6788   /* Use a control ping for synchronization */
6789   MPING (CONTROL_PING, mp_ping);
6790   S (mp_ping);
6791
6792   W (ret);
6793   return ret;
6794 }
6795
6796 static int
6797 api_bridge_domain_add_del (vat_main_t * vam)
6798 {
6799   unformat_input_t *i = vam->input;
6800   vl_api_bridge_domain_add_del_t *mp;
6801   u32 bd_id = ~0;
6802   u8 is_add = 1;
6803   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6804   u8 *bd_tag = NULL;
6805   u32 mac_age = 0;
6806   int ret;
6807
6808   /* Parse args required to build the message */
6809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6810     {
6811       if (unformat (i, "bd_id %d", &bd_id))
6812         ;
6813       else if (unformat (i, "flood %d", &flood))
6814         ;
6815       else if (unformat (i, "uu-flood %d", &uu_flood))
6816         ;
6817       else if (unformat (i, "forward %d", &forward))
6818         ;
6819       else if (unformat (i, "learn %d", &learn))
6820         ;
6821       else if (unformat (i, "arp-term %d", &arp_term))
6822         ;
6823       else if (unformat (i, "mac-age %d", &mac_age))
6824         ;
6825       else if (unformat (i, "bd-tag %s", &bd_tag))
6826         ;
6827       else if (unformat (i, "del"))
6828         {
6829           is_add = 0;
6830           flood = uu_flood = forward = learn = 0;
6831         }
6832       else
6833         break;
6834     }
6835
6836   if (bd_id == ~0)
6837     {
6838       errmsg ("missing bridge domain");
6839       ret = -99;
6840       goto done;
6841     }
6842
6843   if (mac_age > 255)
6844     {
6845       errmsg ("mac age must be less than 256 ");
6846       ret = -99;
6847       goto done;
6848     }
6849
6850   if ((bd_tag) && (vec_len (bd_tag) > 63))
6851     {
6852       errmsg ("bd-tag cannot be longer than 63");
6853       ret = -99;
6854       goto done;
6855     }
6856
6857   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6858
6859   mp->bd_id = ntohl (bd_id);
6860   mp->flood = flood;
6861   mp->uu_flood = uu_flood;
6862   mp->forward = forward;
6863   mp->learn = learn;
6864   mp->arp_term = arp_term;
6865   mp->is_add = is_add;
6866   mp->mac_age = (u8) mac_age;
6867   if (bd_tag)
6868     {
6869       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6870       mp->bd_tag[vec_len (bd_tag)] = 0;
6871     }
6872   S (mp);
6873   W (ret);
6874
6875 done:
6876   vec_free (bd_tag);
6877   return ret;
6878 }
6879
6880 static int
6881 api_l2fib_flush_bd (vat_main_t * vam)
6882 {
6883   unformat_input_t *i = vam->input;
6884   vl_api_l2fib_flush_bd_t *mp;
6885   u32 bd_id = ~0;
6886   int ret;
6887
6888   /* Parse args required to build the message */
6889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6890     {
6891       if (unformat (i, "bd_id %d", &bd_id));
6892       else
6893         break;
6894     }
6895
6896   if (bd_id == ~0)
6897     {
6898       errmsg ("missing bridge domain");
6899       return -99;
6900     }
6901
6902   M (L2FIB_FLUSH_BD, mp);
6903
6904   mp->bd_id = htonl (bd_id);
6905
6906   S (mp);
6907   W (ret);
6908   return ret;
6909 }
6910
6911 static int
6912 api_l2fib_flush_int (vat_main_t * vam)
6913 {
6914   unformat_input_t *i = vam->input;
6915   vl_api_l2fib_flush_int_t *mp;
6916   u32 sw_if_index = ~0;
6917   int ret;
6918
6919   /* Parse args required to build the message */
6920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6921     {
6922       if (unformat (i, "sw_if_index %d", &sw_if_index));
6923       else
6924         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6925       else
6926         break;
6927     }
6928
6929   if (sw_if_index == ~0)
6930     {
6931       errmsg ("missing interface name or sw_if_index");
6932       return -99;
6933     }
6934
6935   M (L2FIB_FLUSH_INT, mp);
6936
6937   mp->sw_if_index = ntohl (sw_if_index);
6938
6939   S (mp);
6940   W (ret);
6941   return ret;
6942 }
6943
6944 static int
6945 api_l2fib_add_del (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_l2fib_add_del_t *mp;
6949   f64 timeout;
6950   u8 mac[6] = { 0 };
6951   u8 mac_set = 0;
6952   u32 bd_id;
6953   u8 bd_id_set = 0;
6954   u32 sw_if_index = 0;
6955   u8 sw_if_index_set = 0;
6956   u8 is_add = 1;
6957   u8 static_mac = 0;
6958   u8 filter_mac = 0;
6959   u8 bvi_mac = 0;
6960   int count = 1;
6961   f64 before = 0;
6962   int j;
6963
6964   /* Parse args required to build the message */
6965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6966     {
6967       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6968         mac_set = 1;
6969       else if (unformat (i, "bd_id %d", &bd_id))
6970         bd_id_set = 1;
6971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6972         sw_if_index_set = 1;
6973       else if (unformat (i, "sw_if"))
6974         {
6975           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6976             {
6977               if (unformat
6978                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6979                 sw_if_index_set = 1;
6980             }
6981           else
6982             break;
6983         }
6984       else if (unformat (i, "static"))
6985         static_mac = 1;
6986       else if (unformat (i, "filter"))
6987         {
6988           filter_mac = 1;
6989           static_mac = 1;
6990         }
6991       else if (unformat (i, "bvi"))
6992         {
6993           bvi_mac = 1;
6994           static_mac = 1;
6995         }
6996       else if (unformat (i, "del"))
6997         is_add = 0;
6998       else if (unformat (i, "count %d", &count))
6999         ;
7000       else
7001         break;
7002     }
7003
7004   if (mac_set == 0)
7005     {
7006       errmsg ("missing mac address");
7007       return -99;
7008     }
7009
7010   if (bd_id_set == 0)
7011     {
7012       errmsg ("missing bridge domain");
7013       return -99;
7014     }
7015
7016   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7017     {
7018       errmsg ("missing interface name or sw_if_index");
7019       return -99;
7020     }
7021
7022   if (count > 1)
7023     {
7024       /* Turn on async mode */
7025       vam->async_mode = 1;
7026       vam->async_errors = 0;
7027       before = vat_time_now (vam);
7028     }
7029
7030   for (j = 0; j < count; j++)
7031     {
7032       M (L2FIB_ADD_DEL, mp);
7033
7034       clib_memcpy (mp->mac, mac, 6);
7035       mp->bd_id = ntohl (bd_id);
7036       mp->is_add = is_add;
7037       mp->sw_if_index = ntohl (sw_if_index);
7038
7039       if (is_add)
7040         {
7041           mp->static_mac = static_mac;
7042           mp->filter_mac = filter_mac;
7043           mp->bvi_mac = bvi_mac;
7044         }
7045       increment_mac_address (mac);
7046       /* send it... */
7047       S (mp);
7048     }
7049
7050   if (count > 1)
7051     {
7052       vl_api_control_ping_t *mp_ping;
7053       f64 after;
7054
7055       /* Shut off async mode */
7056       vam->async_mode = 0;
7057
7058       MPING (CONTROL_PING, mp_ping);
7059       S (mp_ping);
7060
7061       timeout = vat_time_now (vam) + 1.0;
7062       while (vat_time_now (vam) < timeout)
7063         if (vam->result_ready == 1)
7064           goto out;
7065       vam->retval = -99;
7066
7067     out:
7068       if (vam->retval == -99)
7069         errmsg ("timeout");
7070
7071       if (vam->async_errors > 0)
7072         {
7073           errmsg ("%d asynchronous errors", vam->async_errors);
7074           vam->retval = -98;
7075         }
7076       vam->async_errors = 0;
7077       after = vat_time_now (vam);
7078
7079       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7080              count, after - before, count / (after - before));
7081     }
7082   else
7083     {
7084       int ret;
7085
7086       /* Wait for a reply... */
7087       W (ret);
7088       return ret;
7089     }
7090   /* Return the good/bad news */
7091   return (vam->retval);
7092 }
7093
7094 static int
7095 api_bridge_domain_set_mac_age (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_bridge_domain_set_mac_age_t *mp;
7099   u32 bd_id = ~0;
7100   u32 mac_age = 0;
7101   int ret;
7102
7103   /* Parse args required to build the message */
7104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7105     {
7106       if (unformat (i, "bd_id %d", &bd_id));
7107       else if (unformat (i, "mac-age %d", &mac_age));
7108       else
7109         break;
7110     }
7111
7112   if (bd_id == ~0)
7113     {
7114       errmsg ("missing bridge domain");
7115       return -99;
7116     }
7117
7118   if (mac_age > 255)
7119     {
7120       errmsg ("mac age must be less than 256 ");
7121       return -99;
7122     }
7123
7124   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7125
7126   mp->bd_id = htonl (bd_id);
7127   mp->mac_age = (u8) mac_age;
7128
7129   S (mp);
7130   W (ret);
7131   return ret;
7132 }
7133
7134 static int
7135 api_l2_flags (vat_main_t * vam)
7136 {
7137   unformat_input_t *i = vam->input;
7138   vl_api_l2_flags_t *mp;
7139   u32 sw_if_index;
7140   u32 flags = 0;
7141   u8 sw_if_index_set = 0;
7142   u8 is_set = 0;
7143   int ret;
7144
7145   /* Parse args required to build the message */
7146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7147     {
7148       if (unformat (i, "sw_if_index %d", &sw_if_index))
7149         sw_if_index_set = 1;
7150       else if (unformat (i, "sw_if"))
7151         {
7152           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7153             {
7154               if (unformat
7155                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7156                 sw_if_index_set = 1;
7157             }
7158           else
7159             break;
7160         }
7161       else if (unformat (i, "learn"))
7162         flags |= L2_LEARN;
7163       else if (unformat (i, "forward"))
7164         flags |= L2_FWD;
7165       else if (unformat (i, "flood"))
7166         flags |= L2_FLOOD;
7167       else if (unformat (i, "uu-flood"))
7168         flags |= L2_UU_FLOOD;
7169       else if (unformat (i, "arp-term"))
7170         flags |= L2_ARP_TERM;
7171       else if (unformat (i, "off"))
7172         is_set = 0;
7173       else if (unformat (i, "disable"))
7174         is_set = 0;
7175       else
7176         break;
7177     }
7178
7179   if (sw_if_index_set == 0)
7180     {
7181       errmsg ("missing interface name or sw_if_index");
7182       return -99;
7183     }
7184
7185   M (L2_FLAGS, mp);
7186
7187   mp->sw_if_index = ntohl (sw_if_index);
7188   mp->feature_bitmap = ntohl (flags);
7189   mp->is_set = is_set;
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_bridge_flags (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_bridge_flags_t *mp;
7201   u32 bd_id;
7202   u8 bd_id_set = 0;
7203   u8 is_set = 1;
7204   bd_flags_t flags = 0;
7205   int ret;
7206
7207   /* Parse args required to build the message */
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "bd_id %d", &bd_id))
7211         bd_id_set = 1;
7212       else if (unformat (i, "learn"))
7213         flags |= BRIDGE_API_FLAG_LEARN;
7214       else if (unformat (i, "forward"))
7215         flags |= BRIDGE_API_FLAG_FWD;
7216       else if (unformat (i, "flood"))
7217         flags |= BRIDGE_API_FLAG_FLOOD;
7218       else if (unformat (i, "uu-flood"))
7219         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7220       else if (unformat (i, "arp-term"))
7221         flags |= BRIDGE_API_FLAG_ARP_TERM;
7222       else if (unformat (i, "off"))
7223         is_set = 0;
7224       else if (unformat (i, "disable"))
7225         is_set = 0;
7226       else
7227         break;
7228     }
7229
7230   if (bd_id_set == 0)
7231     {
7232       errmsg ("missing bridge domain");
7233       return -99;
7234     }
7235
7236   M (BRIDGE_FLAGS, mp);
7237
7238   mp->bd_id = ntohl (bd_id);
7239   mp->flags = ntohl (flags);
7240   mp->is_set = is_set;
7241
7242   S (mp);
7243   W (ret);
7244   return ret;
7245 }
7246
7247 static int
7248 api_bd_ip_mac_add_del (vat_main_t * vam)
7249 {
7250   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7251   vl_api_mac_address_t mac = { 0 };
7252   unformat_input_t *i = vam->input;
7253   vl_api_bd_ip_mac_add_del_t *mp;
7254   u32 bd_id;
7255   u8 is_add = 1;
7256   u8 bd_id_set = 0;
7257   u8 ip_set = 0;
7258   u8 mac_set = 0;
7259   int ret;
7260
7261
7262   /* Parse args required to build the message */
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264     {
7265       if (unformat (i, "bd_id %d", &bd_id))
7266         {
7267           bd_id_set++;
7268         }
7269       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7270         {
7271           ip_set++;
7272         }
7273       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7274         {
7275           mac_set++;
7276         }
7277       else if (unformat (i, "del"))
7278         is_add = 0;
7279       else
7280         break;
7281     }
7282
7283   if (bd_id_set == 0)
7284     {
7285       errmsg ("missing bridge domain");
7286       return -99;
7287     }
7288   else if (ip_set == 0)
7289     {
7290       errmsg ("missing IP address");
7291       return -99;
7292     }
7293   else if (mac_set == 0)
7294     {
7295       errmsg ("missing MAC address");
7296       return -99;
7297     }
7298
7299   M (BD_IP_MAC_ADD_DEL, mp);
7300
7301   mp->entry.bd_id = ntohl (bd_id);
7302   mp->is_add = is_add;
7303
7304   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7305   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7306
7307   S (mp);
7308   W (ret);
7309   return ret;
7310 }
7311
7312 static int
7313 api_bd_ip_mac_flush (vat_main_t * vam)
7314 {
7315   unformat_input_t *i = vam->input;
7316   vl_api_bd_ip_mac_flush_t *mp;
7317   u32 bd_id;
7318   u8 bd_id_set = 0;
7319   int ret;
7320
7321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7322     {
7323       if (unformat (i, "bd_id %d", &bd_id))
7324         {
7325           bd_id_set++;
7326         }
7327       else
7328         break;
7329     }
7330
7331   if (bd_id_set == 0)
7332     {
7333       errmsg ("missing bridge domain");
7334       return -99;
7335     }
7336
7337   M (BD_IP_MAC_FLUSH, mp);
7338
7339   mp->bd_id = ntohl (bd_id);
7340
7341   S (mp);
7342   W (ret);
7343   return ret;
7344 }
7345
7346 static void vl_api_bd_ip_mac_details_t_handler
7347   (vl_api_bd_ip_mac_details_t * mp)
7348 {
7349   vat_main_t *vam = &vat_main;
7350
7351   print (vam->ofp,
7352          "\n%-5d %U %U",
7353          ntohl (mp->entry.bd_id),
7354          format_vl_api_mac_address, mp->entry.mac,
7355          format_vl_api_address, &mp->entry.ip);
7356 }
7357
7358 static void vl_api_bd_ip_mac_details_t_handler_json
7359   (vl_api_bd_ip_mac_details_t * mp)
7360 {
7361   vat_main_t *vam = &vat_main;
7362   vat_json_node_t *node = NULL;
7363
7364   if (VAT_JSON_ARRAY != vam->json_tree.type)
7365     {
7366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7367       vat_json_init_array (&vam->json_tree);
7368     }
7369   node = vat_json_array_add (&vam->json_tree);
7370
7371   vat_json_init_object (node);
7372   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7373   vat_json_object_add_string_copy (node, "mac_address",
7374                                    format (0, "%U", format_vl_api_mac_address,
7375                                            &mp->entry.mac));
7376   u8 *ip = 0;
7377
7378   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7379   vat_json_object_add_string_copy (node, "ip_address", ip);
7380   vec_free (ip);
7381 }
7382
7383 static int
7384 api_bd_ip_mac_dump (vat_main_t * vam)
7385 {
7386   unformat_input_t *i = vam->input;
7387   vl_api_bd_ip_mac_dump_t *mp;
7388   vl_api_control_ping_t *mp_ping;
7389   int ret;
7390   u32 bd_id;
7391   u8 bd_id_set = 0;
7392
7393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7394     {
7395       if (unformat (i, "bd_id %d", &bd_id))
7396         {
7397           bd_id_set++;
7398         }
7399       else
7400         break;
7401     }
7402
7403   print (vam->ofp,
7404          "\n%-5s %-7s %-20s %-30s",
7405          "bd_id", "is_ipv6", "mac_address", "ip_address");
7406
7407   /* Dump Bridge Domain Ip to Mac entries */
7408   M (BD_IP_MAC_DUMP, mp);
7409
7410   if (bd_id_set)
7411     mp->bd_id = htonl (bd_id);
7412   else
7413     mp->bd_id = ~0;
7414
7415   S (mp);
7416
7417   /* Use a control ping for synchronization */
7418   MPING (CONTROL_PING, mp_ping);
7419   S (mp_ping);
7420
7421   W (ret);
7422   return ret;
7423 }
7424
7425 static int
7426 api_tap_create_v2 (vat_main_t * vam)
7427 {
7428   unformat_input_t *i = vam->input;
7429   vl_api_tap_create_v2_t *mp;
7430 #define TAP_FLAG_GSO (1 << 0)
7431   u8 mac_address[6];
7432   u8 random_mac = 1;
7433   u32 id = ~0;
7434   u8 *host_if_name = 0;
7435   u8 *host_ns = 0;
7436   u8 host_mac_addr[6];
7437   u8 host_mac_addr_set = 0;
7438   u8 *host_bridge = 0;
7439   ip4_address_t host_ip4_addr;
7440   ip4_address_t host_ip4_gw;
7441   u8 host_ip4_gw_set = 0;
7442   u32 host_ip4_prefix_len = 0;
7443   ip6_address_t host_ip6_addr;
7444   ip6_address_t host_ip6_gw;
7445   u8 host_ip6_gw_set = 0;
7446   u32 host_ip6_prefix_len = 0;
7447   u8 host_mtu_set = 0;
7448   u32 host_mtu_size = 0;
7449   u32 tap_flags = 0;
7450   int ret;
7451   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7452
7453   clib_memset (mac_address, 0, sizeof (mac_address));
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7459         {
7460           random_mac = 0;
7461         }
7462       else if (unformat (i, "id %u", &id))
7463         ;
7464       else if (unformat (i, "host-if-name %s", &host_if_name))
7465         ;
7466       else if (unformat (i, "host-ns %s", &host_ns))
7467         ;
7468       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7469                          host_mac_addr))
7470         host_mac_addr_set = 1;
7471       else if (unformat (i, "host-bridge %s", &host_bridge))
7472         ;
7473       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7474                          &host_ip4_addr, &host_ip4_prefix_len))
7475         ;
7476       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7477                          &host_ip6_addr, &host_ip6_prefix_len))
7478         ;
7479       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7480                          &host_ip4_gw))
7481         host_ip4_gw_set = 1;
7482       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7483                          &host_ip6_gw))
7484         host_ip6_gw_set = 1;
7485       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7486         ;
7487       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7488         ;
7489       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7490         host_mtu_set = 1;
7491       else if (unformat (i, "no-gso"))
7492         tap_flags &= ~TAP_FLAG_GSO;
7493       else if (unformat (i, "gso"))
7494         tap_flags |= TAP_FLAG_GSO;
7495       else
7496         break;
7497     }
7498
7499   if (vec_len (host_if_name) > 63)
7500     {
7501       errmsg ("tap name too long. ");
7502       return -99;
7503     }
7504   if (vec_len (host_ns) > 63)
7505     {
7506       errmsg ("host name space too long. ");
7507       return -99;
7508     }
7509   if (vec_len (host_bridge) > 63)
7510     {
7511       errmsg ("host bridge name too long. ");
7512       return -99;
7513     }
7514   if (host_ip4_prefix_len > 32)
7515     {
7516       errmsg ("host ip4 prefix length not valid. ");
7517       return -99;
7518     }
7519   if (host_ip6_prefix_len > 128)
7520     {
7521       errmsg ("host ip6 prefix length not valid. ");
7522       return -99;
7523     }
7524   if (!is_pow2 (rx_ring_sz))
7525     {
7526       errmsg ("rx ring size must be power of 2. ");
7527       return -99;
7528     }
7529   if (rx_ring_sz > 32768)
7530     {
7531       errmsg ("rx ring size must be 32768 or lower. ");
7532       return -99;
7533     }
7534   if (!is_pow2 (tx_ring_sz))
7535     {
7536       errmsg ("tx ring size must be power of 2. ");
7537       return -99;
7538     }
7539   if (tx_ring_sz > 32768)
7540     {
7541       errmsg ("tx ring size must be 32768 or lower. ");
7542       return -99;
7543     }
7544   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7545     {
7546       errmsg ("host MTU size must be in between 64 and 65355. ");
7547       return -99;
7548     }
7549
7550   /* Construct the API message */
7551   M (TAP_CREATE_V2, mp);
7552
7553   mp->use_random_mac = random_mac;
7554
7555   mp->id = ntohl (id);
7556   mp->host_namespace_set = host_ns != 0;
7557   mp->host_bridge_set = host_bridge != 0;
7558   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7559   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7560   mp->rx_ring_sz = ntohs (rx_ring_sz);
7561   mp->tx_ring_sz = ntohs (tx_ring_sz);
7562   mp->host_mtu_set = host_mtu_set;
7563   mp->host_mtu_size = ntohl (host_mtu_size);
7564   mp->tap_flags = ntohl (tap_flags);
7565
7566   if (random_mac == 0)
7567     clib_memcpy (mp->mac_address, mac_address, 6);
7568   if (host_mac_addr_set)
7569     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7570   if (host_if_name)
7571     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7572   if (host_ns)
7573     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7574   if (host_bridge)
7575     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7576   if (host_ip4_prefix_len)
7577     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7578   if (host_ip6_prefix_len)
7579     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7580   if (host_ip4_gw_set)
7581     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7582   if (host_ip6_gw_set)
7583     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7584
7585   vec_free (host_ns);
7586   vec_free (host_if_name);
7587   vec_free (host_bridge);
7588
7589   /* send it... */
7590   S (mp);
7591
7592   /* Wait for a reply... */
7593   W (ret);
7594   return ret;
7595 }
7596
7597 static int
7598 api_tap_delete_v2 (vat_main_t * vam)
7599 {
7600   unformat_input_t *i = vam->input;
7601   vl_api_tap_delete_v2_t *mp;
7602   u32 sw_if_index = ~0;
7603   u8 sw_if_index_set = 0;
7604   int ret;
7605
7606   /* Parse args required to build the message */
7607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7608     {
7609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7610         sw_if_index_set = 1;
7611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7612         sw_if_index_set = 1;
7613       else
7614         break;
7615     }
7616
7617   if (sw_if_index_set == 0)
7618     {
7619       errmsg ("missing vpp interface name. ");
7620       return -99;
7621     }
7622
7623   /* Construct the API message */
7624   M (TAP_DELETE_V2, mp);
7625
7626   mp->sw_if_index = ntohl (sw_if_index);
7627
7628   /* send it... */
7629   S (mp);
7630
7631   /* Wait for a reply... */
7632   W (ret);
7633   return ret;
7634 }
7635
7636 uword
7637 unformat_pci_addr (unformat_input_t * input, va_list * args)
7638 {
7639   struct pci_addr_t
7640   {
7641     u16 domain;
7642     u8 bus;
7643     u8 slot:5;
7644     u8 function:3;
7645   } *addr;
7646   addr = va_arg (*args, struct pci_addr_t *);
7647   u32 x[4];
7648
7649   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7650     return 0;
7651
7652   addr->domain = x[0];
7653   addr->bus = x[1];
7654   addr->slot = x[2];
7655   addr->function = x[3];
7656
7657   return 1;
7658 }
7659
7660 static int
7661 api_virtio_pci_create (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_virtio_pci_create_t *mp;
7665   u8 mac_address[6];
7666   u8 random_mac = 1;
7667   u8 gso_enabled = 0;
7668   u32 pci_addr = 0;
7669   u64 features = (u64) ~ (0ULL);
7670   int ret;
7671
7672   clib_memset (mac_address, 0, sizeof (mac_address));
7673
7674   /* Parse args required to build the message */
7675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7676     {
7677       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7678         {
7679           random_mac = 0;
7680         }
7681       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7682         ;
7683       else if (unformat (i, "features 0x%llx", &features))
7684         ;
7685       else if (unformat (i, "gso-enabled"))
7686         gso_enabled = 1;
7687       else
7688         break;
7689     }
7690
7691   if (pci_addr == 0)
7692     {
7693       errmsg ("pci address must be non zero. ");
7694       return -99;
7695     }
7696
7697   /* Construct the API message */
7698   M (VIRTIO_PCI_CREATE, mp);
7699
7700   mp->use_random_mac = random_mac;
7701
7702   mp->pci_addr = htonl (pci_addr);
7703   mp->features = clib_host_to_net_u64 (features);
7704   mp->gso_enabled = gso_enabled;
7705
7706   if (random_mac == 0)
7707     clib_memcpy (mp->mac_address, mac_address, 6);
7708
7709   /* send it... */
7710   S (mp);
7711
7712   /* Wait for a reply... */
7713   W (ret);
7714   return ret;
7715 }
7716
7717 static int
7718 api_virtio_pci_delete (vat_main_t * vam)
7719 {
7720   unformat_input_t *i = vam->input;
7721   vl_api_virtio_pci_delete_t *mp;
7722   u32 sw_if_index = ~0;
7723   u8 sw_if_index_set = 0;
7724   int ret;
7725
7726   /* Parse args required to build the message */
7727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7728     {
7729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7730         sw_if_index_set = 1;
7731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7732         sw_if_index_set = 1;
7733       else
7734         break;
7735     }
7736
7737   if (sw_if_index_set == 0)
7738     {
7739       errmsg ("missing vpp interface name. ");
7740       return -99;
7741     }
7742
7743   /* Construct the API message */
7744   M (VIRTIO_PCI_DELETE, mp);
7745
7746   mp->sw_if_index = htonl (sw_if_index);
7747
7748   /* send it... */
7749   S (mp);
7750
7751   /* Wait for a reply... */
7752   W (ret);
7753   return ret;
7754 }
7755
7756 static int
7757 api_bond_create (vat_main_t * vam)
7758 {
7759   unformat_input_t *i = vam->input;
7760   vl_api_bond_create_t *mp;
7761   u8 mac_address[6];
7762   u8 custom_mac = 0;
7763   int ret;
7764   u8 mode;
7765   u8 lb;
7766   u8 mode_is_set = 0;
7767   u32 id = ~0;
7768
7769   clib_memset (mac_address, 0, sizeof (mac_address));
7770   lb = BOND_LB_L2;
7771
7772   /* Parse args required to build the message */
7773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7774     {
7775       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7776         mode_is_set = 1;
7777       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7778                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7779         ;
7780       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7781                          mac_address))
7782         custom_mac = 1;
7783       else if (unformat (i, "id %u", &id))
7784         ;
7785       else
7786         break;
7787     }
7788
7789   if (mode_is_set == 0)
7790     {
7791       errmsg ("Missing bond mode. ");
7792       return -99;
7793     }
7794
7795   /* Construct the API message */
7796   M (BOND_CREATE, mp);
7797
7798   mp->use_custom_mac = custom_mac;
7799
7800   mp->mode = mode;
7801   mp->lb = lb;
7802   mp->id = htonl (id);
7803
7804   if (custom_mac)
7805     clib_memcpy (mp->mac_address, mac_address, 6);
7806
7807   /* send it... */
7808   S (mp);
7809
7810   /* Wait for a reply... */
7811   W (ret);
7812   return ret;
7813 }
7814
7815 static int
7816 api_bond_delete (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_bond_delete_t *mp;
7820   u32 sw_if_index = ~0;
7821   u8 sw_if_index_set = 0;
7822   int ret;
7823
7824   /* Parse args required to build the message */
7825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7826     {
7827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7828         sw_if_index_set = 1;
7829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7830         sw_if_index_set = 1;
7831       else
7832         break;
7833     }
7834
7835   if (sw_if_index_set == 0)
7836     {
7837       errmsg ("missing vpp interface name. ");
7838       return -99;
7839     }
7840
7841   /* Construct the API message */
7842   M (BOND_DELETE, mp);
7843
7844   mp->sw_if_index = ntohl (sw_if_index);
7845
7846   /* send it... */
7847   S (mp);
7848
7849   /* Wait for a reply... */
7850   W (ret);
7851   return ret;
7852 }
7853
7854 static int
7855 api_bond_enslave (vat_main_t * vam)
7856 {
7857   unformat_input_t *i = vam->input;
7858   vl_api_bond_enslave_t *mp;
7859   u32 bond_sw_if_index;
7860   int ret;
7861   u8 is_passive;
7862   u8 is_long_timeout;
7863   u32 bond_sw_if_index_is_set = 0;
7864   u32 sw_if_index;
7865   u8 sw_if_index_is_set = 0;
7866
7867   /* Parse args required to build the message */
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "sw_if_index %d", &sw_if_index))
7871         sw_if_index_is_set = 1;
7872       else if (unformat (i, "bond %u", &bond_sw_if_index))
7873         bond_sw_if_index_is_set = 1;
7874       else if (unformat (i, "passive %d", &is_passive))
7875         ;
7876       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7877         ;
7878       else
7879         break;
7880     }
7881
7882   if (bond_sw_if_index_is_set == 0)
7883     {
7884       errmsg ("Missing bond sw_if_index. ");
7885       return -99;
7886     }
7887   if (sw_if_index_is_set == 0)
7888     {
7889       errmsg ("Missing slave sw_if_index. ");
7890       return -99;
7891     }
7892
7893   /* Construct the API message */
7894   M (BOND_ENSLAVE, mp);
7895
7896   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7897   mp->sw_if_index = ntohl (sw_if_index);
7898   mp->is_long_timeout = is_long_timeout;
7899   mp->is_passive = is_passive;
7900
7901   /* send it... */
7902   S (mp);
7903
7904   /* Wait for a reply... */
7905   W (ret);
7906   return ret;
7907 }
7908
7909 static int
7910 api_bond_detach_slave (vat_main_t * vam)
7911 {
7912   unformat_input_t *i = vam->input;
7913   vl_api_bond_detach_slave_t *mp;
7914   u32 sw_if_index = ~0;
7915   u8 sw_if_index_set = 0;
7916   int ret;
7917
7918   /* Parse args required to build the message */
7919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7920     {
7921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7922         sw_if_index_set = 1;
7923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7924         sw_if_index_set = 1;
7925       else
7926         break;
7927     }
7928
7929   if (sw_if_index_set == 0)
7930     {
7931       errmsg ("missing vpp interface name. ");
7932       return -99;
7933     }
7934
7935   /* Construct the API message */
7936   M (BOND_DETACH_SLAVE, mp);
7937
7938   mp->sw_if_index = ntohl (sw_if_index);
7939
7940   /* send it... */
7941   S (mp);
7942
7943   /* Wait for a reply... */
7944   W (ret);
7945   return ret;
7946 }
7947
7948 static int
7949 api_ip_table_add_del (vat_main_t * vam)
7950 {
7951   unformat_input_t *i = vam->input;
7952   vl_api_ip_table_add_del_t *mp;
7953   u32 table_id = ~0;
7954   u8 is_ipv6 = 0;
7955   u8 is_add = 1;
7956   int ret = 0;
7957
7958   /* Parse args required to build the message */
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "ipv6"))
7962         is_ipv6 = 1;
7963       else if (unformat (i, "del"))
7964         is_add = 0;
7965       else if (unformat (i, "add"))
7966         is_add = 1;
7967       else if (unformat (i, "table %d", &table_id))
7968         ;
7969       else
7970         {
7971           clib_warning ("parse error '%U'", format_unformat_error, i);
7972           return -99;
7973         }
7974     }
7975
7976   if (~0 == table_id)
7977     {
7978       errmsg ("missing table-ID");
7979       return -99;
7980     }
7981
7982   /* Construct the API message */
7983   M (IP_TABLE_ADD_DEL, mp);
7984
7985   mp->table.table_id = ntohl (table_id);
7986   mp->table.is_ip6 = is_ipv6;
7987   mp->is_add = is_add;
7988
7989   /* send it... */
7990   S (mp);
7991
7992   /* Wait for a reply... */
7993   W (ret);
7994
7995   return ret;
7996 }
7997
7998 uword
7999 unformat_fib_path (unformat_input_t * input, va_list * args)
8000 {
8001   vat_main_t *vam = va_arg (*args, vat_main_t *);
8002   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8003   u32 weight, preference;
8004   mpls_label_t out_label;
8005
8006   clib_memset (path, 0, sizeof (*path));
8007   path->weight = 1;
8008   path->sw_if_index = ~0;
8009   path->rpf_id = ~0;
8010   path->n_labels = 0;
8011
8012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8013     {
8014       if (unformat (input, "%U %U",
8015                     unformat_vl_api_ip4_address,
8016                     &path->nh.address.ip4,
8017                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8018         {
8019           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8020         }
8021       else if (unformat (input, "%U %U",
8022                          unformat_vl_api_ip6_address,
8023                          &path->nh.address.ip6,
8024                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8025         {
8026           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8027         }
8028       else if (unformat (input, "weight %u", &weight))
8029         {
8030           path->weight = weight;
8031         }
8032       else if (unformat (input, "preference %u", &preference))
8033         {
8034           path->preference = preference;
8035         }
8036       else if (unformat (input, "%U next-hop-table %d",
8037                          unformat_vl_api_ip4_address,
8038                          &path->nh.address.ip4, &path->table_id))
8039         {
8040           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8041         }
8042       else if (unformat (input, "%U next-hop-table %d",
8043                          unformat_vl_api_ip6_address,
8044                          &path->nh.address.ip6, &path->table_id))
8045         {
8046           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8047         }
8048       else if (unformat (input, "%U",
8049                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8050         {
8051           /*
8052            * the recursive next-hops are by default in the default table
8053            */
8054           path->table_id = 0;
8055           path->sw_if_index = ~0;
8056           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8057         }
8058       else if (unformat (input, "%U",
8059                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8060         {
8061           /*
8062            * the recursive next-hops are by default in the default table
8063            */
8064           path->table_id = 0;
8065           path->sw_if_index = ~0;
8066           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8067         }
8068       else if (unformat (input, "resolve-via-host"))
8069         {
8070           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8071         }
8072       else if (unformat (input, "resolve-via-attached"))
8073         {
8074           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8075         }
8076       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8077         {
8078           path->type = FIB_API_PATH_TYPE_LOCAL;
8079           path->sw_if_index = ~0;
8080           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8081         }
8082       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8083         {
8084           path->type = FIB_API_PATH_TYPE_LOCAL;
8085           path->sw_if_index = ~0;
8086           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8087         }
8088       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8089         ;
8090       else if (unformat (input, "via-label %d", &path->nh.via_label))
8091         {
8092           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8093           path->sw_if_index = ~0;
8094         }
8095       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8096         {
8097           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8098           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8099         }
8100       else if (unformat (input, "local"))
8101         {
8102           path->type = FIB_API_PATH_TYPE_LOCAL;
8103         }
8104       else if (unformat (input, "out-labels"))
8105         {
8106           while (unformat (input, "%d", &out_label))
8107             {
8108               path->label_stack[path->n_labels].label = out_label;
8109               path->label_stack[path->n_labels].is_uniform = 0;
8110               path->label_stack[path->n_labels].ttl = 64;
8111               path->n_labels++;
8112             }
8113         }
8114       else if (unformat (input, "via"))
8115         {
8116           /* new path, back up and return */
8117           unformat_put_input (input);
8118           unformat_put_input (input);
8119           unformat_put_input (input);
8120           unformat_put_input (input);
8121           break;
8122         }
8123       else
8124         {
8125           return (0);
8126         }
8127     }
8128
8129   path->proto = ntohl (path->proto);
8130   path->type = ntohl (path->type);
8131   path->flags = ntohl (path->flags);
8132   path->table_id = ntohl (path->table_id);
8133   path->sw_if_index = ntohl (path->sw_if_index);
8134
8135   return (1);
8136 }
8137
8138 static int
8139 api_ip_route_add_del (vat_main_t * vam)
8140 {
8141   unformat_input_t *i = vam->input;
8142   vl_api_ip_route_add_del_t *mp;
8143   u32 vrf_id = 0;
8144   u8 is_add = 1;
8145   u8 is_multipath = 0;
8146   u8 prefix_set = 0;
8147   u8 path_count = 0;
8148   vl_api_prefix_t pfx = { };
8149   vl_api_fib_path_t paths[8];
8150   int count = 1;
8151   int j;
8152   f64 before = 0;
8153   u32 random_add_del = 0;
8154   u32 *random_vector = 0;
8155   u32 random_seed = 0xdeaddabe;
8156
8157   /* Parse args required to build the message */
8158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8159     {
8160       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8161         prefix_set = 1;
8162       else if (unformat (i, "del"))
8163         is_add = 0;
8164       else if (unformat (i, "add"))
8165         is_add = 1;
8166       else if (unformat (i, "vrf %d", &vrf_id))
8167         ;
8168       else if (unformat (i, "count %d", &count))
8169         ;
8170       else if (unformat (i, "random"))
8171         random_add_del = 1;
8172       else if (unformat (i, "multipath"))
8173         is_multipath = 1;
8174       else if (unformat (i, "seed %d", &random_seed))
8175         ;
8176       else
8177         if (unformat
8178             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8179         {
8180           path_count++;
8181           if (8 == path_count)
8182             {
8183               errmsg ("max 8 paths");
8184               return -99;
8185             }
8186         }
8187       else
8188         {
8189           clib_warning ("parse error '%U'", format_unformat_error, i);
8190           return -99;
8191         }
8192     }
8193
8194   if (!path_count)
8195     {
8196       errmsg ("specify a path; via ...");
8197       return -99;
8198     }
8199   if (prefix_set == 0)
8200     {
8201       errmsg ("missing prefix");
8202       return -99;
8203     }
8204
8205   /* Generate a pile of unique, random routes */
8206   if (random_add_del)
8207     {
8208       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8209       u32 this_random_address;
8210       uword *random_hash;
8211
8212       random_hash = hash_create (count, sizeof (uword));
8213
8214       hash_set (random_hash, i->as_u32, 1);
8215       for (j = 0; j <= count; j++)
8216         {
8217           do
8218             {
8219               this_random_address = random_u32 (&random_seed);
8220               this_random_address =
8221                 clib_host_to_net_u32 (this_random_address);
8222             }
8223           while (hash_get (random_hash, this_random_address));
8224           vec_add1 (random_vector, this_random_address);
8225           hash_set (random_hash, this_random_address, 1);
8226         }
8227       hash_free (random_hash);
8228       set_ip4_address (&pfx.address, random_vector[0]);
8229     }
8230
8231   if (count > 1)
8232     {
8233       /* Turn on async mode */
8234       vam->async_mode = 1;
8235       vam->async_errors = 0;
8236       before = vat_time_now (vam);
8237     }
8238
8239   for (j = 0; j < count; j++)
8240     {
8241       /* Construct the API message */
8242       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8243
8244       mp->is_add = is_add;
8245       mp->is_multipath = is_multipath;
8246
8247       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8248       mp->route.table_id = ntohl (vrf_id);
8249       mp->route.n_paths = path_count;
8250
8251       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8252
8253       if (random_add_del)
8254         set_ip4_address (&pfx.address, random_vector[j + 1]);
8255       else
8256         increment_address (&pfx.address);
8257       /* send it... */
8258       S (mp);
8259       /* If we receive SIGTERM, stop now... */
8260       if (vam->do_exit)
8261         break;
8262     }
8263
8264   /* When testing multiple add/del ops, use a control-ping to sync */
8265   if (count > 1)
8266     {
8267       vl_api_control_ping_t *mp_ping;
8268       f64 after;
8269       f64 timeout;
8270
8271       /* Shut off async mode */
8272       vam->async_mode = 0;
8273
8274       MPING (CONTROL_PING, mp_ping);
8275       S (mp_ping);
8276
8277       timeout = vat_time_now (vam) + 1.0;
8278       while (vat_time_now (vam) < timeout)
8279         if (vam->result_ready == 1)
8280           goto out;
8281       vam->retval = -99;
8282
8283     out:
8284       if (vam->retval == -99)
8285         errmsg ("timeout");
8286
8287       if (vam->async_errors > 0)
8288         {
8289           errmsg ("%d asynchronous errors", vam->async_errors);
8290           vam->retval = -98;
8291         }
8292       vam->async_errors = 0;
8293       after = vat_time_now (vam);
8294
8295       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8296       if (j > 0)
8297         count = j;
8298
8299       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8300              count, after - before, count / (after - before));
8301     }
8302   else
8303     {
8304       int ret;
8305
8306       /* Wait for a reply... */
8307       W (ret);
8308       return ret;
8309     }
8310
8311   /* Return the good/bad news */
8312   return (vam->retval);
8313 }
8314
8315 static int
8316 api_ip_mroute_add_del (vat_main_t * vam)
8317 {
8318   unformat_input_t *i = vam->input;
8319   u8 path_set = 0, prefix_set = 0, is_add = 1;
8320   vl_api_ip_mroute_add_del_t *mp;
8321   mfib_entry_flags_t eflags = 0;
8322   vl_api_mfib_path_t path;
8323   vl_api_mprefix_t pfx = { };
8324   u32 vrf_id = 0;
8325   int ret;
8326
8327   /* Parse args required to build the message */
8328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8329     {
8330       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8331         {
8332           prefix_set = 1;
8333           pfx.grp_address_length = htons (pfx.grp_address_length);
8334         }
8335       else if (unformat (i, "del"))
8336         is_add = 0;
8337       else if (unformat (i, "add"))
8338         is_add = 1;
8339       else if (unformat (i, "vrf %d", &vrf_id))
8340         ;
8341       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8342         path.itf_flags = htonl (path.itf_flags);
8343       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8344         ;
8345       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8346         path_set = 1;
8347       else
8348         {
8349           clib_warning ("parse error '%U'", format_unformat_error, i);
8350           return -99;
8351         }
8352     }
8353
8354   if (prefix_set == 0)
8355     {
8356       errmsg ("missing addresses\n");
8357       return -99;
8358     }
8359   if (path_set == 0)
8360     {
8361       errmsg ("missing path\n");
8362       return -99;
8363     }
8364
8365   /* Construct the API message */
8366   M (IP_MROUTE_ADD_DEL, mp);
8367
8368   mp->is_add = is_add;
8369   mp->is_multipath = 1;
8370
8371   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8372   mp->route.table_id = htonl (vrf_id);
8373   mp->route.n_paths = 1;
8374   mp->route.entry_flags = htonl (eflags);
8375
8376   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8377
8378   /* send it... */
8379   S (mp);
8380   /* Wait for a reply... */
8381   W (ret);
8382   return ret;
8383 }
8384
8385 static int
8386 api_mpls_table_add_del (vat_main_t * vam)
8387 {
8388   unformat_input_t *i = vam->input;
8389   vl_api_mpls_table_add_del_t *mp;
8390   u32 table_id = ~0;
8391   u8 is_add = 1;
8392   int ret = 0;
8393
8394   /* Parse args required to build the message */
8395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (i, "table %d", &table_id))
8398         ;
8399       else if (unformat (i, "del"))
8400         is_add = 0;
8401       else if (unformat (i, "add"))
8402         is_add = 1;
8403       else
8404         {
8405           clib_warning ("parse error '%U'", format_unformat_error, i);
8406           return -99;
8407         }
8408     }
8409
8410   if (~0 == table_id)
8411     {
8412       errmsg ("missing table-ID");
8413       return -99;
8414     }
8415
8416   /* Construct the API message */
8417   M (MPLS_TABLE_ADD_DEL, mp);
8418
8419   mp->mt_table.mt_table_id = ntohl (table_id);
8420   mp->mt_is_add = is_add;
8421
8422   /* send it... */
8423   S (mp);
8424
8425   /* Wait for a reply... */
8426   W (ret);
8427
8428   return ret;
8429 }
8430
8431 static int
8432 api_mpls_route_add_del (vat_main_t * vam)
8433 {
8434   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8435   mpls_label_t local_label = MPLS_LABEL_INVALID;
8436   unformat_input_t *i = vam->input;
8437   vl_api_mpls_route_add_del_t *mp;
8438   vl_api_fib_path_t paths[8];
8439   int count = 1, j;
8440   f64 before = 0;
8441
8442   /* Parse args required to build the message */
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "%d", &local_label))
8446         ;
8447       else if (unformat (i, "eos"))
8448         is_eos = 1;
8449       else if (unformat (i, "non-eos"))
8450         is_eos = 0;
8451       else if (unformat (i, "del"))
8452         is_add = 0;
8453       else if (unformat (i, "add"))
8454         is_add = 1;
8455       else if (unformat (i, "multipath"))
8456         is_multipath = 1;
8457       else if (unformat (i, "count %d", &count))
8458         ;
8459       else
8460         if (unformat
8461             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8462         {
8463           path_count++;
8464           if (8 == path_count)
8465             {
8466               errmsg ("max 8 paths");
8467               return -99;
8468             }
8469         }
8470       else
8471         {
8472           clib_warning ("parse error '%U'", format_unformat_error, i);
8473           return -99;
8474         }
8475     }
8476
8477   if (!path_count)
8478     {
8479       errmsg ("specify a path; via ...");
8480       return -99;
8481     }
8482
8483   if (MPLS_LABEL_INVALID == local_label)
8484     {
8485       errmsg ("missing label");
8486       return -99;
8487     }
8488
8489   if (count > 1)
8490     {
8491       /* Turn on async mode */
8492       vam->async_mode = 1;
8493       vam->async_errors = 0;
8494       before = vat_time_now (vam);
8495     }
8496
8497   for (j = 0; j < count; j++)
8498     {
8499       /* Construct the API message */
8500       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8501
8502       mp->mr_is_add = is_add;
8503       mp->mr_is_multipath = is_multipath;
8504
8505       mp->mr_route.mr_label = local_label;
8506       mp->mr_route.mr_eos = is_eos;
8507       mp->mr_route.mr_table_id = 0;
8508       mp->mr_route.mr_n_paths = path_count;
8509
8510       clib_memcpy (&mp->mr_route.mr_paths, paths,
8511                    sizeof (paths[0]) * path_count);
8512
8513       local_label++;
8514
8515       /* send it... */
8516       S (mp);
8517       /* If we receive SIGTERM, stop now... */
8518       if (vam->do_exit)
8519         break;
8520     }
8521
8522   /* When testing multiple add/del ops, use a control-ping to sync */
8523   if (count > 1)
8524     {
8525       vl_api_control_ping_t *mp_ping;
8526       f64 after;
8527       f64 timeout;
8528
8529       /* Shut off async mode */
8530       vam->async_mode = 0;
8531
8532       MPING (CONTROL_PING, mp_ping);
8533       S (mp_ping);
8534
8535       timeout = vat_time_now (vam) + 1.0;
8536       while (vat_time_now (vam) < timeout)
8537         if (vam->result_ready == 1)
8538           goto out;
8539       vam->retval = -99;
8540
8541     out:
8542       if (vam->retval == -99)
8543         errmsg ("timeout");
8544
8545       if (vam->async_errors > 0)
8546         {
8547           errmsg ("%d asynchronous errors", vam->async_errors);
8548           vam->retval = -98;
8549         }
8550       vam->async_errors = 0;
8551       after = vat_time_now (vam);
8552
8553       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8554       if (j > 0)
8555         count = j;
8556
8557       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8558              count, after - before, count / (after - before));
8559     }
8560   else
8561     {
8562       int ret;
8563
8564       /* Wait for a reply... */
8565       W (ret);
8566       return ret;
8567     }
8568
8569   /* Return the good/bad news */
8570   return (vam->retval);
8571   return (0);
8572 }
8573
8574 static int
8575 api_mpls_ip_bind_unbind (vat_main_t * vam)
8576 {
8577   unformat_input_t *i = vam->input;
8578   vl_api_mpls_ip_bind_unbind_t *mp;
8579   u32 ip_table_id = 0;
8580   u8 is_bind = 1;
8581   vl_api_prefix_t pfx;
8582   u8 prefix_set = 0;
8583   mpls_label_t local_label = MPLS_LABEL_INVALID;
8584   int ret;
8585
8586   /* Parse args required to build the message */
8587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8588     {
8589       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8590         prefix_set = 1;
8591       else if (unformat (i, "%d", &local_label))
8592         ;
8593       else if (unformat (i, "table-id %d", &ip_table_id))
8594         ;
8595       else if (unformat (i, "unbind"))
8596         is_bind = 0;
8597       else if (unformat (i, "bind"))
8598         is_bind = 1;
8599       else
8600         {
8601           clib_warning ("parse error '%U'", format_unformat_error, i);
8602           return -99;
8603         }
8604     }
8605
8606   if (!prefix_set)
8607     {
8608       errmsg ("IP prefix not set");
8609       return -99;
8610     }
8611
8612   if (MPLS_LABEL_INVALID == local_label)
8613     {
8614       errmsg ("missing label");
8615       return -99;
8616     }
8617
8618   /* Construct the API message */
8619   M (MPLS_IP_BIND_UNBIND, mp);
8620
8621   mp->mb_is_bind = is_bind;
8622   mp->mb_ip_table_id = ntohl (ip_table_id);
8623   mp->mb_mpls_table_id = 0;
8624   mp->mb_label = ntohl (local_label);
8625   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply... */
8631   W (ret);
8632   return ret;
8633   return (0);
8634 }
8635
8636 static int
8637 api_sr_mpls_policy_add (vat_main_t * vam)
8638 {
8639   unformat_input_t *i = vam->input;
8640   vl_api_sr_mpls_policy_add_t *mp;
8641   u32 bsid = 0;
8642   u32 weight = 1;
8643   u8 type = 0;
8644   u8 n_segments = 0;
8645   u32 sid;
8646   u32 *segments = NULL;
8647   int ret;
8648
8649   /* Parse args required to build the message */
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "bsid %d", &bsid))
8653         ;
8654       else if (unformat (i, "weight %d", &weight))
8655         ;
8656       else if (unformat (i, "spray"))
8657         type = 1;
8658       else if (unformat (i, "next %d", &sid))
8659         {
8660           n_segments += 1;
8661           vec_add1 (segments, htonl (sid));
8662         }
8663       else
8664         {
8665           clib_warning ("parse error '%U'", format_unformat_error, i);
8666           return -99;
8667         }
8668     }
8669
8670   if (bsid == 0)
8671     {
8672       errmsg ("bsid not set");
8673       return -99;
8674     }
8675
8676   if (n_segments == 0)
8677     {
8678       errmsg ("no sid in segment stack");
8679       return -99;
8680     }
8681
8682   /* Construct the API message */
8683   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8684
8685   mp->bsid = htonl (bsid);
8686   mp->weight = htonl (weight);
8687   mp->type = type;
8688   mp->n_segments = n_segments;
8689   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8690   vec_free (segments);
8691
8692   /* send it... */
8693   S (mp);
8694
8695   /* Wait for a reply... */
8696   W (ret);
8697   return ret;
8698 }
8699
8700 static int
8701 api_sr_mpls_policy_del (vat_main_t * vam)
8702 {
8703   unformat_input_t *i = vam->input;
8704   vl_api_sr_mpls_policy_del_t *mp;
8705   u32 bsid = 0;
8706   int ret;
8707
8708   /* Parse args required to build the message */
8709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8710     {
8711       if (unformat (i, "bsid %d", &bsid))
8712         ;
8713       else
8714         {
8715           clib_warning ("parse error '%U'", format_unformat_error, i);
8716           return -99;
8717         }
8718     }
8719
8720   if (bsid == 0)
8721     {
8722       errmsg ("bsid not set");
8723       return -99;
8724     }
8725
8726   /* Construct the API message */
8727   M (SR_MPLS_POLICY_DEL, mp);
8728
8729   mp->bsid = htonl (bsid);
8730
8731   /* send it... */
8732   S (mp);
8733
8734   /* Wait for a reply... */
8735   W (ret);
8736   return ret;
8737 }
8738
8739 static int
8740 api_bier_table_add_del (vat_main_t * vam)
8741 {
8742   unformat_input_t *i = vam->input;
8743   vl_api_bier_table_add_del_t *mp;
8744   u8 is_add = 1;
8745   u32 set = 0, sub_domain = 0, hdr_len = 3;
8746   mpls_label_t local_label = MPLS_LABEL_INVALID;
8747   int ret;
8748
8749   /* Parse args required to build the message */
8750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8751     {
8752       if (unformat (i, "sub-domain %d", &sub_domain))
8753         ;
8754       else if (unformat (i, "set %d", &set))
8755         ;
8756       else if (unformat (i, "label %d", &local_label))
8757         ;
8758       else if (unformat (i, "hdr-len %d", &hdr_len))
8759         ;
8760       else if (unformat (i, "add"))
8761         is_add = 1;
8762       else if (unformat (i, "del"))
8763         is_add = 0;
8764       else
8765         {
8766           clib_warning ("parse error '%U'", format_unformat_error, i);
8767           return -99;
8768         }
8769     }
8770
8771   if (MPLS_LABEL_INVALID == local_label)
8772     {
8773       errmsg ("missing label\n");
8774       return -99;
8775     }
8776
8777   /* Construct the API message */
8778   M (BIER_TABLE_ADD_DEL, mp);
8779
8780   mp->bt_is_add = is_add;
8781   mp->bt_label = ntohl (local_label);
8782   mp->bt_tbl_id.bt_set = set;
8783   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8784   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8785
8786   /* send it... */
8787   S (mp);
8788
8789   /* Wait for a reply... */
8790   W (ret);
8791
8792   return (ret);
8793 }
8794
8795 static int
8796 api_bier_route_add_del (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_bier_route_add_del_t *mp;
8800   u8 is_add = 1;
8801   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8802   ip4_address_t v4_next_hop_address;
8803   ip6_address_t v6_next_hop_address;
8804   u8 next_hop_set = 0;
8805   u8 next_hop_proto_is_ip4 = 1;
8806   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8807   int ret;
8808
8809   /* Parse args required to build the message */
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8813         {
8814           next_hop_proto_is_ip4 = 1;
8815           next_hop_set = 1;
8816         }
8817       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8818         {
8819           next_hop_proto_is_ip4 = 0;
8820           next_hop_set = 1;
8821         }
8822       if (unformat (i, "sub-domain %d", &sub_domain))
8823         ;
8824       else if (unformat (i, "set %d", &set))
8825         ;
8826       else if (unformat (i, "hdr-len %d", &hdr_len))
8827         ;
8828       else if (unformat (i, "bp %d", &bp))
8829         ;
8830       else if (unformat (i, "add"))
8831         is_add = 1;
8832       else if (unformat (i, "del"))
8833         is_add = 0;
8834       else if (unformat (i, "out-label %d", &next_hop_out_label))
8835         ;
8836       else
8837         {
8838           clib_warning ("parse error '%U'", format_unformat_error, i);
8839           return -99;
8840         }
8841     }
8842
8843   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8844     {
8845       errmsg ("next hop / label set\n");
8846       return -99;
8847     }
8848   if (0 == bp)
8849     {
8850       errmsg ("bit=position not set\n");
8851       return -99;
8852     }
8853
8854   /* Construct the API message */
8855   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8856
8857   mp->br_is_add = is_add;
8858   mp->br_route.br_tbl_id.bt_set = set;
8859   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8860   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8861   mp->br_route.br_bp = ntohs (bp);
8862   mp->br_route.br_n_paths = 1;
8863   mp->br_route.br_paths[0].n_labels = 1;
8864   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8865   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8866                                     FIB_API_PATH_NH_PROTO_IP4 :
8867                                     FIB_API_PATH_NH_PROTO_IP6);
8868
8869   if (next_hop_proto_is_ip4)
8870     {
8871       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8872                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8873     }
8874   else
8875     {
8876       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8877                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8878     }
8879
8880   /* send it... */
8881   S (mp);
8882
8883   /* Wait for a reply... */
8884   W (ret);
8885
8886   return (ret);
8887 }
8888
8889 static int
8890 api_proxy_arp_add_del (vat_main_t * vam)
8891 {
8892   unformat_input_t *i = vam->input;
8893   vl_api_proxy_arp_add_del_t *mp;
8894   u32 vrf_id = 0;
8895   u8 is_add = 1;
8896   vl_api_ip4_address_t lo, hi;
8897   u8 range_set = 0;
8898   int ret;
8899
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "vrf %d", &vrf_id))
8903         ;
8904       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8905                          unformat_vl_api_ip4_address, &hi))
8906         range_set = 1;
8907       else if (unformat (i, "del"))
8908         is_add = 0;
8909       else
8910         {
8911           clib_warning ("parse error '%U'", format_unformat_error, i);
8912           return -99;
8913         }
8914     }
8915
8916   if (range_set == 0)
8917     {
8918       errmsg ("address range not set");
8919       return -99;
8920     }
8921
8922   M (PROXY_ARP_ADD_DEL, mp);
8923
8924   mp->proxy.table_id = ntohl (vrf_id);
8925   mp->is_add = is_add;
8926   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8927   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8928
8929   S (mp);
8930   W (ret);
8931   return ret;
8932 }
8933
8934 static int
8935 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8936 {
8937   unformat_input_t *i = vam->input;
8938   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8939   u32 sw_if_index;
8940   u8 enable = 1;
8941   u8 sw_if_index_set = 0;
8942   int ret;
8943
8944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8945     {
8946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8947         sw_if_index_set = 1;
8948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8949         sw_if_index_set = 1;
8950       else if (unformat (i, "enable"))
8951         enable = 1;
8952       else if (unformat (i, "disable"))
8953         enable = 0;
8954       else
8955         {
8956           clib_warning ("parse error '%U'", format_unformat_error, i);
8957           return -99;
8958         }
8959     }
8960
8961   if (sw_if_index_set == 0)
8962     {
8963       errmsg ("missing interface name or sw_if_index");
8964       return -99;
8965     }
8966
8967   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8968
8969   mp->sw_if_index = ntohl (sw_if_index);
8970   mp->enable_disable = enable;
8971
8972   S (mp);
8973   W (ret);
8974   return ret;
8975 }
8976
8977 static int
8978 api_mpls_tunnel_add_del (vat_main_t * vam)
8979 {
8980   unformat_input_t *i = vam->input;
8981   vl_api_mpls_tunnel_add_del_t *mp;
8982
8983   vl_api_fib_path_t paths[8];
8984   u32 sw_if_index = ~0;
8985   u8 path_count = 0;
8986   u8 l2_only = 0;
8987   u8 is_add = 1;
8988   int ret;
8989
8990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (i, "add"))
8993         is_add = 1;
8994       else
8995         if (unformat
8996             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8997         is_add = 0;
8998       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8999         is_add = 0;
9000       else if (unformat (i, "l2-only"))
9001         l2_only = 1;
9002       else
9003         if (unformat
9004             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9005         {
9006           path_count++;
9007           if (8 == path_count)
9008             {
9009               errmsg ("max 8 paths");
9010               return -99;
9011             }
9012         }
9013       else
9014         {
9015           clib_warning ("parse error '%U'", format_unformat_error, i);
9016           return -99;
9017         }
9018     }
9019
9020   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9021
9022   mp->mt_is_add = is_add;
9023   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9024   mp->mt_tunnel.mt_l2_only = l2_only;
9025   mp->mt_tunnel.mt_is_multicast = 0;
9026   mp->mt_tunnel.mt_n_paths = path_count;
9027
9028   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9029                sizeof (paths[0]) * path_count);
9030
9031   S (mp);
9032   W (ret);
9033   return ret;
9034 }
9035
9036 static int
9037 api_sw_interface_set_unnumbered (vat_main_t * vam)
9038 {
9039   unformat_input_t *i = vam->input;
9040   vl_api_sw_interface_set_unnumbered_t *mp;
9041   u32 sw_if_index;
9042   u32 unnum_sw_index = ~0;
9043   u8 is_add = 1;
9044   u8 sw_if_index_set = 0;
9045   int ret;
9046
9047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9048     {
9049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9050         sw_if_index_set = 1;
9051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9052         sw_if_index_set = 1;
9053       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9054         ;
9055       else if (unformat (i, "del"))
9056         is_add = 0;
9057       else
9058         {
9059           clib_warning ("parse error '%U'", format_unformat_error, i);
9060           return -99;
9061         }
9062     }
9063
9064   if (sw_if_index_set == 0)
9065     {
9066       errmsg ("missing interface name or sw_if_index");
9067       return -99;
9068     }
9069
9070   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9071
9072   mp->sw_if_index = ntohl (sw_if_index);
9073   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9074   mp->is_add = is_add;
9075
9076   S (mp);
9077   W (ret);
9078   return ret;
9079 }
9080
9081 static int
9082 api_ip_neighbor_add_del (vat_main_t * vam)
9083 {
9084   vl_api_mac_address_t mac_address;
9085   unformat_input_t *i = vam->input;
9086   vl_api_ip_neighbor_add_del_t *mp;
9087   vl_api_address_t ip_address;
9088   u32 sw_if_index;
9089   u8 sw_if_index_set = 0;
9090   u8 is_add = 1;
9091   u8 mac_set = 0;
9092   u8 address_set = 0;
9093   int ret;
9094   ip_neighbor_flags_t flags;
9095
9096   flags = IP_NEIGHBOR_FLAG_NONE;
9097   clib_memset (&ip_address, 0, sizeof (ip_address));
9098   clib_memset (&mac_address, 0, sizeof (mac_address));
9099
9100   /* Parse args required to build the message */
9101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9104         {
9105           mac_set = 1;
9106         }
9107       else if (unformat (i, "del"))
9108         is_add = 0;
9109       else
9110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9111         sw_if_index_set = 1;
9112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9113         sw_if_index_set = 1;
9114       else if (unformat (i, "static"))
9115         flags |= IP_NEIGHBOR_FLAG_STATIC;
9116       else if (unformat (i, "no-fib-entry"))
9117         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9118       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9119         address_set = 1;
9120       else
9121         {
9122           clib_warning ("parse error '%U'", format_unformat_error, i);
9123           return -99;
9124         }
9125     }
9126
9127   if (sw_if_index_set == 0)
9128     {
9129       errmsg ("missing interface name or sw_if_index");
9130       return -99;
9131     }
9132   if (!address_set)
9133     {
9134       errmsg ("no address set");
9135       return -99;
9136     }
9137
9138   /* Construct the API message */
9139   M (IP_NEIGHBOR_ADD_DEL, mp);
9140
9141   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9142   mp->is_add = is_add;
9143   mp->neighbor.flags = htonl (flags);
9144   if (mac_set)
9145     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9146                  sizeof (mac_address));
9147   if (address_set)
9148     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9149
9150   /* send it... */
9151   S (mp);
9152
9153   /* Wait for a reply, return good/bad news  */
9154   W (ret);
9155   return ret;
9156 }
9157
9158 static int
9159 api_create_vlan_subif (vat_main_t * vam)
9160 {
9161   unformat_input_t *i = vam->input;
9162   vl_api_create_vlan_subif_t *mp;
9163   u32 sw_if_index;
9164   u8 sw_if_index_set = 0;
9165   u32 vlan_id;
9166   u8 vlan_id_set = 0;
9167   int ret;
9168
9169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9170     {
9171       if (unformat (i, "sw_if_index %d", &sw_if_index))
9172         sw_if_index_set = 1;
9173       else
9174         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9175         sw_if_index_set = 1;
9176       else if (unformat (i, "vlan %d", &vlan_id))
9177         vlan_id_set = 1;
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (sw_if_index_set == 0)
9186     {
9187       errmsg ("missing interface name or sw_if_index");
9188       return -99;
9189     }
9190
9191   if (vlan_id_set == 0)
9192     {
9193       errmsg ("missing vlan_id");
9194       return -99;
9195     }
9196   M (CREATE_VLAN_SUBIF, mp);
9197
9198   mp->sw_if_index = ntohl (sw_if_index);
9199   mp->vlan_id = ntohl (vlan_id);
9200
9201   S (mp);
9202   W (ret);
9203   return ret;
9204 }
9205
9206 #define foreach_create_subif_bit                \
9207 _(no_tags)                                      \
9208 _(one_tag)                                      \
9209 _(two_tags)                                     \
9210 _(dot1ad)                                       \
9211 _(exact_match)                                  \
9212 _(default_sub)                                  \
9213 _(outer_vlan_id_any)                            \
9214 _(inner_vlan_id_any)
9215
9216 static int
9217 api_create_subif (vat_main_t * vam)
9218 {
9219   unformat_input_t *i = vam->input;
9220   vl_api_create_subif_t *mp;
9221   u32 sw_if_index;
9222   u8 sw_if_index_set = 0;
9223   u32 sub_id;
9224   u8 sub_id_set = 0;
9225   u32 no_tags = 0;
9226   u32 one_tag = 0;
9227   u32 two_tags = 0;
9228   u32 dot1ad = 0;
9229   u32 exact_match = 0;
9230   u32 default_sub = 0;
9231   u32 outer_vlan_id_any = 0;
9232   u32 inner_vlan_id_any = 0;
9233   u32 tmp;
9234   u16 outer_vlan_id = 0;
9235   u16 inner_vlan_id = 0;
9236   int ret;
9237
9238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9239     {
9240       if (unformat (i, "sw_if_index %d", &sw_if_index))
9241         sw_if_index_set = 1;
9242       else
9243         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9244         sw_if_index_set = 1;
9245       else if (unformat (i, "sub_id %d", &sub_id))
9246         sub_id_set = 1;
9247       else if (unformat (i, "outer_vlan_id %d", &tmp))
9248         outer_vlan_id = tmp;
9249       else if (unformat (i, "inner_vlan_id %d", &tmp))
9250         inner_vlan_id = tmp;
9251
9252 #define _(a) else if (unformat (i, #a)) a = 1 ;
9253       foreach_create_subif_bit
9254 #undef _
9255         else
9256         {
9257           clib_warning ("parse error '%U'", format_unformat_error, i);
9258           return -99;
9259         }
9260     }
9261
9262   if (sw_if_index_set == 0)
9263     {
9264       errmsg ("missing interface name or sw_if_index");
9265       return -99;
9266     }
9267
9268   if (sub_id_set == 0)
9269     {
9270       errmsg ("missing sub_id");
9271       return -99;
9272     }
9273   M (CREATE_SUBIF, mp);
9274
9275   mp->sw_if_index = ntohl (sw_if_index);
9276   mp->sub_id = ntohl (sub_id);
9277
9278 #define _(a) mp->a = a;
9279   foreach_create_subif_bit;
9280 #undef _
9281
9282   mp->outer_vlan_id = ntohs (outer_vlan_id);
9283   mp->inner_vlan_id = ntohs (inner_vlan_id);
9284
9285   S (mp);
9286   W (ret);
9287   return ret;
9288 }
9289
9290 static int
9291 api_reset_fib (vat_main_t * vam)
9292 {
9293   unformat_input_t *i = vam->input;
9294   vl_api_reset_fib_t *mp;
9295   u32 vrf_id = 0;
9296   u8 is_ipv6 = 0;
9297   u8 vrf_id_set = 0;
9298
9299   int ret;
9300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9301     {
9302       if (unformat (i, "vrf %d", &vrf_id))
9303         vrf_id_set = 1;
9304       else if (unformat (i, "ipv6"))
9305         is_ipv6 = 1;
9306       else
9307         {
9308           clib_warning ("parse error '%U'", format_unformat_error, i);
9309           return -99;
9310         }
9311     }
9312
9313   if (vrf_id_set == 0)
9314     {
9315       errmsg ("missing vrf id");
9316       return -99;
9317     }
9318
9319   M (RESET_FIB, mp);
9320
9321   mp->vrf_id = ntohl (vrf_id);
9322   mp->is_ipv6 = is_ipv6;
9323
9324   S (mp);
9325   W (ret);
9326   return ret;
9327 }
9328
9329 static int
9330 api_dhcp_proxy_config (vat_main_t * vam)
9331 {
9332   unformat_input_t *i = vam->input;
9333   vl_api_dhcp_proxy_config_t *mp;
9334   u32 rx_vrf_id = 0;
9335   u32 server_vrf_id = 0;
9336   u8 is_add = 1;
9337   u8 v4_address_set = 0;
9338   u8 v6_address_set = 0;
9339   ip4_address_t v4address;
9340   ip6_address_t v6address;
9341   u8 v4_src_address_set = 0;
9342   u8 v6_src_address_set = 0;
9343   ip4_address_t v4srcaddress;
9344   ip6_address_t v6srcaddress;
9345   int ret;
9346
9347   /* Parse args required to build the message */
9348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (i, "del"))
9351         is_add = 0;
9352       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9353         ;
9354       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9355         ;
9356       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9357         v4_address_set = 1;
9358       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9359         v6_address_set = 1;
9360       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9361         v4_src_address_set = 1;
9362       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9363         v6_src_address_set = 1;
9364       else
9365         break;
9366     }
9367
9368   if (v4_address_set && v6_address_set)
9369     {
9370       errmsg ("both v4 and v6 server addresses set");
9371       return -99;
9372     }
9373   if (!v4_address_set && !v6_address_set)
9374     {
9375       errmsg ("no server addresses set");
9376       return -99;
9377     }
9378
9379   if (v4_src_address_set && v6_src_address_set)
9380     {
9381       errmsg ("both v4 and v6  src addresses set");
9382       return -99;
9383     }
9384   if (!v4_src_address_set && !v6_src_address_set)
9385     {
9386       errmsg ("no src addresses set");
9387       return -99;
9388     }
9389
9390   if (!(v4_src_address_set && v4_address_set) &&
9391       !(v6_src_address_set && v6_address_set))
9392     {
9393       errmsg ("no matching server and src addresses set");
9394       return -99;
9395     }
9396
9397   /* Construct the API message */
9398   M (DHCP_PROXY_CONFIG, mp);
9399
9400   mp->is_add = is_add;
9401   mp->rx_vrf_id = ntohl (rx_vrf_id);
9402   mp->server_vrf_id = ntohl (server_vrf_id);
9403   if (v6_address_set)
9404     {
9405       mp->is_ipv6 = 1;
9406       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9407       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9408     }
9409   else
9410     {
9411       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9412       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9413     }
9414
9415   /* send it... */
9416   S (mp);
9417
9418   /* Wait for a reply, return good/bad news  */
9419   W (ret);
9420   return ret;
9421 }
9422
9423 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9424 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9425
9426 static void
9427 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9428 {
9429   vat_main_t *vam = &vat_main;
9430   u32 i, count = mp->count;
9431   vl_api_dhcp_server_t *s;
9432
9433   if (mp->is_ipv6)
9434     print (vam->ofp,
9435            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9436            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9437            ntohl (mp->rx_vrf_id),
9438            format_ip6_address, mp->dhcp_src_address,
9439            mp->vss_type, mp->vss_vpn_ascii_id,
9440            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9441   else
9442     print (vam->ofp,
9443            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9444            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9445            ntohl (mp->rx_vrf_id),
9446            format_ip4_address, mp->dhcp_src_address,
9447            mp->vss_type, mp->vss_vpn_ascii_id,
9448            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9449
9450   for (i = 0; i < count; i++)
9451     {
9452       s = &mp->servers[i];
9453
9454       if (mp->is_ipv6)
9455         print (vam->ofp,
9456                " Server Table-ID %d, Server Address %U",
9457                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9458       else
9459         print (vam->ofp,
9460                " Server Table-ID %d, Server Address %U",
9461                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9462     }
9463 }
9464
9465 static void vl_api_dhcp_proxy_details_t_handler_json
9466   (vl_api_dhcp_proxy_details_t * mp)
9467 {
9468   vat_main_t *vam = &vat_main;
9469   vat_json_node_t *node = NULL;
9470   u32 i, count = mp->count;
9471   struct in_addr ip4;
9472   struct in6_addr ip6;
9473   vl_api_dhcp_server_t *s;
9474
9475   if (VAT_JSON_ARRAY != vam->json_tree.type)
9476     {
9477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9478       vat_json_init_array (&vam->json_tree);
9479     }
9480   node = vat_json_array_add (&vam->json_tree);
9481
9482   vat_json_init_object (node);
9483   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9484   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9485                              sizeof (mp->vss_type));
9486   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9487                                    mp->vss_vpn_ascii_id);
9488   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9489   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9490
9491   if (mp->is_ipv6)
9492     {
9493       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9494       vat_json_object_add_ip6 (node, "src_address", ip6);
9495     }
9496   else
9497     {
9498       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9499       vat_json_object_add_ip4 (node, "src_address", ip4);
9500     }
9501
9502   for (i = 0; i < count; i++)
9503     {
9504       s = &mp->servers[i];
9505
9506       vat_json_object_add_uint (node, "server-table-id",
9507                                 ntohl (s->server_vrf_id));
9508
9509       if (mp->is_ipv6)
9510         {
9511           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9512           vat_json_object_add_ip4 (node, "src_address", ip4);
9513         }
9514       else
9515         {
9516           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9517           vat_json_object_add_ip6 (node, "server_address", ip6);
9518         }
9519     }
9520 }
9521
9522 static int
9523 api_dhcp_proxy_dump (vat_main_t * vam)
9524 {
9525   unformat_input_t *i = vam->input;
9526   vl_api_control_ping_t *mp_ping;
9527   vl_api_dhcp_proxy_dump_t *mp;
9528   u8 is_ipv6 = 0;
9529   int ret;
9530
9531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9532     {
9533       if (unformat (i, "ipv6"))
9534         is_ipv6 = 1;
9535       else
9536         {
9537           clib_warning ("parse error '%U'", format_unformat_error, i);
9538           return -99;
9539         }
9540     }
9541
9542   M (DHCP_PROXY_DUMP, mp);
9543
9544   mp->is_ip6 = is_ipv6;
9545   S (mp);
9546
9547   /* Use a control ping for synchronization */
9548   MPING (CONTROL_PING, mp_ping);
9549   S (mp_ping);
9550
9551   W (ret);
9552   return ret;
9553 }
9554
9555 static int
9556 api_dhcp_proxy_set_vss (vat_main_t * vam)
9557 {
9558   unformat_input_t *i = vam->input;
9559   vl_api_dhcp_proxy_set_vss_t *mp;
9560   u8 is_ipv6 = 0;
9561   u8 is_add = 1;
9562   u32 tbl_id = ~0;
9563   u8 vss_type = VSS_TYPE_DEFAULT;
9564   u8 *vpn_ascii_id = 0;
9565   u32 oui = 0;
9566   u32 fib_id = 0;
9567   int ret;
9568
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "tbl_id %d", &tbl_id))
9572         ;
9573       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9574         vss_type = VSS_TYPE_ASCII;
9575       else if (unformat (i, "fib_id %d", &fib_id))
9576         vss_type = VSS_TYPE_VPN_ID;
9577       else if (unformat (i, "oui %d", &oui))
9578         vss_type = VSS_TYPE_VPN_ID;
9579       else if (unformat (i, "ipv6"))
9580         is_ipv6 = 1;
9581       else if (unformat (i, "del"))
9582         is_add = 0;
9583       else
9584         break;
9585     }
9586
9587   if (tbl_id == ~0)
9588     {
9589       errmsg ("missing tbl_id ");
9590       vec_free (vpn_ascii_id);
9591       return -99;
9592     }
9593
9594   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9595     {
9596       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9597       vec_free (vpn_ascii_id);
9598       return -99;
9599     }
9600
9601   M (DHCP_PROXY_SET_VSS, mp);
9602   mp->tbl_id = ntohl (tbl_id);
9603   mp->vss_type = vss_type;
9604   if (vpn_ascii_id)
9605     {
9606       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9607       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9608     }
9609   mp->vpn_index = ntohl (fib_id);
9610   mp->oui = ntohl (oui);
9611   mp->is_ipv6 = is_ipv6;
9612   mp->is_add = is_add;
9613
9614   S (mp);
9615   W (ret);
9616
9617   vec_free (vpn_ascii_id);
9618   return ret;
9619 }
9620
9621 static int
9622 api_dhcp_client_config (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_dhcp_client_config_t *mp;
9626   u32 sw_if_index;
9627   u8 sw_if_index_set = 0;
9628   u8 is_add = 1;
9629   u8 *hostname = 0;
9630   u8 disable_event = 0;
9631   int ret;
9632
9633   /* Parse args required to build the message */
9634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9635     {
9636       if (unformat (i, "del"))
9637         is_add = 0;
9638       else
9639         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9640         sw_if_index_set = 1;
9641       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9642         sw_if_index_set = 1;
9643       else if (unformat (i, "hostname %s", &hostname))
9644         ;
9645       else if (unformat (i, "disable_event"))
9646         disable_event = 1;
9647       else
9648         break;
9649     }
9650
9651   if (sw_if_index_set == 0)
9652     {
9653       errmsg ("missing interface name or sw_if_index");
9654       return -99;
9655     }
9656
9657   if (vec_len (hostname) > 63)
9658     {
9659       errmsg ("hostname too long");
9660     }
9661   vec_add1 (hostname, 0);
9662
9663   /* Construct the API message */
9664   M (DHCP_CLIENT_CONFIG, mp);
9665
9666   mp->is_add = is_add;
9667   mp->client.sw_if_index = htonl (sw_if_index);
9668   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9669   vec_free (hostname);
9670   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9671   mp->client.pid = htonl (getpid ());
9672
9673   /* send it... */
9674   S (mp);
9675
9676   /* Wait for a reply, return good/bad news  */
9677   W (ret);
9678   return ret;
9679 }
9680
9681 static int
9682 api_set_ip_flow_hash (vat_main_t * vam)
9683 {
9684   unformat_input_t *i = vam->input;
9685   vl_api_set_ip_flow_hash_t *mp;
9686   u32 vrf_id = 0;
9687   u8 is_ipv6 = 0;
9688   u8 vrf_id_set = 0;
9689   u8 src = 0;
9690   u8 dst = 0;
9691   u8 sport = 0;
9692   u8 dport = 0;
9693   u8 proto = 0;
9694   u8 reverse = 0;
9695   int ret;
9696
9697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (i, "vrf %d", &vrf_id))
9700         vrf_id_set = 1;
9701       else if (unformat (i, "ipv6"))
9702         is_ipv6 = 1;
9703       else if (unformat (i, "src"))
9704         src = 1;
9705       else if (unformat (i, "dst"))
9706         dst = 1;
9707       else if (unformat (i, "sport"))
9708         sport = 1;
9709       else if (unformat (i, "dport"))
9710         dport = 1;
9711       else if (unformat (i, "proto"))
9712         proto = 1;
9713       else if (unformat (i, "reverse"))
9714         reverse = 1;
9715
9716       else
9717         {
9718           clib_warning ("parse error '%U'", format_unformat_error, i);
9719           return -99;
9720         }
9721     }
9722
9723   if (vrf_id_set == 0)
9724     {
9725       errmsg ("missing vrf id");
9726       return -99;
9727     }
9728
9729   M (SET_IP_FLOW_HASH, mp);
9730   mp->src = src;
9731   mp->dst = dst;
9732   mp->sport = sport;
9733   mp->dport = dport;
9734   mp->proto = proto;
9735   mp->reverse = reverse;
9736   mp->vrf_id = ntohl (vrf_id);
9737   mp->is_ipv6 = is_ipv6;
9738
9739   S (mp);
9740   W (ret);
9741   return ret;
9742 }
9743
9744 static int
9745 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_sw_interface_ip6_enable_disable_t *mp;
9749   u32 sw_if_index;
9750   u8 sw_if_index_set = 0;
9751   u8 enable = 0;
9752   int ret;
9753
9754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9755     {
9756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9757         sw_if_index_set = 1;
9758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9759         sw_if_index_set = 1;
9760       else if (unformat (i, "enable"))
9761         enable = 1;
9762       else if (unformat (i, "disable"))
9763         enable = 0;
9764       else
9765         {
9766           clib_warning ("parse error '%U'", format_unformat_error, i);
9767           return -99;
9768         }
9769     }
9770
9771   if (sw_if_index_set == 0)
9772     {
9773       errmsg ("missing interface name or sw_if_index");
9774       return -99;
9775     }
9776
9777   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9778
9779   mp->sw_if_index = ntohl (sw_if_index);
9780   mp->enable = enable;
9781
9782   S (mp);
9783   W (ret);
9784   return ret;
9785 }
9786
9787 static int
9788 api_ip6nd_proxy_add_del (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_ip6nd_proxy_add_del_t *mp;
9792   u32 sw_if_index = ~0;
9793   u8 v6_address_set = 0;
9794   vl_api_ip6_address_t v6address;
9795   u8 is_del = 0;
9796   int ret;
9797
9798   /* Parse args required to build the message */
9799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9800     {
9801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9802         ;
9803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9804         ;
9805       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9806         v6_address_set = 1;
9807       if (unformat (i, "del"))
9808         is_del = 1;
9809       else
9810         {
9811           clib_warning ("parse error '%U'", format_unformat_error, i);
9812           return -99;
9813         }
9814     }
9815
9816   if (sw_if_index == ~0)
9817     {
9818       errmsg ("missing interface name or sw_if_index");
9819       return -99;
9820     }
9821   if (!v6_address_set)
9822     {
9823       errmsg ("no address set");
9824       return -99;
9825     }
9826
9827   /* Construct the API message */
9828   M (IP6ND_PROXY_ADD_DEL, mp);
9829
9830   mp->is_del = is_del;
9831   mp->sw_if_index = ntohl (sw_if_index);
9832   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9833
9834   /* send it... */
9835   S (mp);
9836
9837   /* Wait for a reply, return good/bad news  */
9838   W (ret);
9839   return ret;
9840 }
9841
9842 static int
9843 api_ip6nd_proxy_dump (vat_main_t * vam)
9844 {
9845   vl_api_ip6nd_proxy_dump_t *mp;
9846   vl_api_control_ping_t *mp_ping;
9847   int ret;
9848
9849   M (IP6ND_PROXY_DUMP, mp);
9850
9851   S (mp);
9852
9853   /* Use a control ping for synchronization */
9854   MPING (CONTROL_PING, mp_ping);
9855   S (mp_ping);
9856
9857   W (ret);
9858   return ret;
9859 }
9860
9861 static void vl_api_ip6nd_proxy_details_t_handler
9862   (vl_api_ip6nd_proxy_details_t * mp)
9863 {
9864   vat_main_t *vam = &vat_main;
9865
9866   print (vam->ofp, "host %U sw_if_index %d",
9867          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9868 }
9869
9870 static void vl_api_ip6nd_proxy_details_t_handler_json
9871   (vl_api_ip6nd_proxy_details_t * mp)
9872 {
9873   vat_main_t *vam = &vat_main;
9874   struct in6_addr ip6;
9875   vat_json_node_t *node = NULL;
9876
9877   if (VAT_JSON_ARRAY != vam->json_tree.type)
9878     {
9879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9880       vat_json_init_array (&vam->json_tree);
9881     }
9882   node = vat_json_array_add (&vam->json_tree);
9883
9884   vat_json_init_object (node);
9885   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9886
9887   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9888   vat_json_object_add_ip6 (node, "host", ip6);
9889 }
9890
9891 static int
9892 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9893 {
9894   unformat_input_t *i = vam->input;
9895   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9896   u32 sw_if_index;
9897   u8 sw_if_index_set = 0;
9898   u8 v6_address_set = 0;
9899   vl_api_prefix_t pfx;
9900   u8 use_default = 0;
9901   u8 no_advertise = 0;
9902   u8 off_link = 0;
9903   u8 no_autoconfig = 0;
9904   u8 no_onlink = 0;
9905   u8 is_no = 0;
9906   u32 val_lifetime = 0;
9907   u32 pref_lifetime = 0;
9908   int ret;
9909
9910   /* Parse args required to build the message */
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9914         sw_if_index_set = 1;
9915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9916         sw_if_index_set = 1;
9917       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9918         v6_address_set = 1;
9919       else if (unformat (i, "val_life %d", &val_lifetime))
9920         ;
9921       else if (unformat (i, "pref_life %d", &pref_lifetime))
9922         ;
9923       else if (unformat (i, "def"))
9924         use_default = 1;
9925       else if (unformat (i, "noadv"))
9926         no_advertise = 1;
9927       else if (unformat (i, "offl"))
9928         off_link = 1;
9929       else if (unformat (i, "noauto"))
9930         no_autoconfig = 1;
9931       else if (unformat (i, "nolink"))
9932         no_onlink = 1;
9933       else if (unformat (i, "isno"))
9934         is_no = 1;
9935       else
9936         {
9937           clib_warning ("parse error '%U'", format_unformat_error, i);
9938           return -99;
9939         }
9940     }
9941
9942   if (sw_if_index_set == 0)
9943     {
9944       errmsg ("missing interface name or sw_if_index");
9945       return -99;
9946     }
9947   if (!v6_address_set)
9948     {
9949       errmsg ("no address set");
9950       return -99;
9951     }
9952
9953   /* Construct the API message */
9954   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9955
9956   mp->sw_if_index = ntohl (sw_if_index);
9957   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9958   mp->use_default = use_default;
9959   mp->no_advertise = no_advertise;
9960   mp->off_link = off_link;
9961   mp->no_autoconfig = no_autoconfig;
9962   mp->no_onlink = no_onlink;
9963   mp->is_no = is_no;
9964   mp->val_lifetime = ntohl (val_lifetime);
9965   mp->pref_lifetime = ntohl (pref_lifetime);
9966
9967   /* send it... */
9968   S (mp);
9969
9970   /* Wait for a reply, return good/bad news  */
9971   W (ret);
9972   return ret;
9973 }
9974
9975 static int
9976 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9977 {
9978   unformat_input_t *i = vam->input;
9979   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9980   u32 sw_if_index;
9981   u8 sw_if_index_set = 0;
9982   u8 suppress = 0;
9983   u8 managed = 0;
9984   u8 other = 0;
9985   u8 ll_option = 0;
9986   u8 send_unicast = 0;
9987   u8 cease = 0;
9988   u8 is_no = 0;
9989   u8 default_router = 0;
9990   u32 max_interval = 0;
9991   u32 min_interval = 0;
9992   u32 lifetime = 0;
9993   u32 initial_count = 0;
9994   u32 initial_interval = 0;
9995   int ret;
9996
9997
9998   /* Parse args required to build the message */
9999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10002         sw_if_index_set = 1;
10003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10004         sw_if_index_set = 1;
10005       else if (unformat (i, "maxint %d", &max_interval))
10006         ;
10007       else if (unformat (i, "minint %d", &min_interval))
10008         ;
10009       else if (unformat (i, "life %d", &lifetime))
10010         ;
10011       else if (unformat (i, "count %d", &initial_count))
10012         ;
10013       else if (unformat (i, "interval %d", &initial_interval))
10014         ;
10015       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10016         suppress = 1;
10017       else if (unformat (i, "managed"))
10018         managed = 1;
10019       else if (unformat (i, "other"))
10020         other = 1;
10021       else if (unformat (i, "ll"))
10022         ll_option = 1;
10023       else if (unformat (i, "send"))
10024         send_unicast = 1;
10025       else if (unformat (i, "cease"))
10026         cease = 1;
10027       else if (unformat (i, "isno"))
10028         is_no = 1;
10029       else if (unformat (i, "def"))
10030         default_router = 1;
10031       else
10032         {
10033           clib_warning ("parse error '%U'", format_unformat_error, i);
10034           return -99;
10035         }
10036     }
10037
10038   if (sw_if_index_set == 0)
10039     {
10040       errmsg ("missing interface name or sw_if_index");
10041       return -99;
10042     }
10043
10044   /* Construct the API message */
10045   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10046
10047   mp->sw_if_index = ntohl (sw_if_index);
10048   mp->max_interval = ntohl (max_interval);
10049   mp->min_interval = ntohl (min_interval);
10050   mp->lifetime = ntohl (lifetime);
10051   mp->initial_count = ntohl (initial_count);
10052   mp->initial_interval = ntohl (initial_interval);
10053   mp->suppress = suppress;
10054   mp->managed = managed;
10055   mp->other = other;
10056   mp->ll_option = ll_option;
10057   mp->send_unicast = send_unicast;
10058   mp->cease = cease;
10059   mp->is_no = is_no;
10060   mp->default_router = default_router;
10061
10062   /* send it... */
10063   S (mp);
10064
10065   /* Wait for a reply, return good/bad news  */
10066   W (ret);
10067   return ret;
10068 }
10069
10070 static int
10071 api_set_arp_neighbor_limit (vat_main_t * vam)
10072 {
10073   unformat_input_t *i = vam->input;
10074   vl_api_set_arp_neighbor_limit_t *mp;
10075   u32 arp_nbr_limit;
10076   u8 limit_set = 0;
10077   u8 is_ipv6 = 0;
10078   int ret;
10079
10080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10081     {
10082       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10083         limit_set = 1;
10084       else if (unformat (i, "ipv6"))
10085         is_ipv6 = 1;
10086       else
10087         {
10088           clib_warning ("parse error '%U'", format_unformat_error, i);
10089           return -99;
10090         }
10091     }
10092
10093   if (limit_set == 0)
10094     {
10095       errmsg ("missing limit value");
10096       return -99;
10097     }
10098
10099   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10100
10101   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10102   mp->is_ipv6 = is_ipv6;
10103
10104   S (mp);
10105   W (ret);
10106   return ret;
10107 }
10108
10109 static int
10110 api_l2_patch_add_del (vat_main_t * vam)
10111 {
10112   unformat_input_t *i = vam->input;
10113   vl_api_l2_patch_add_del_t *mp;
10114   u32 rx_sw_if_index;
10115   u8 rx_sw_if_index_set = 0;
10116   u32 tx_sw_if_index;
10117   u8 tx_sw_if_index_set = 0;
10118   u8 is_add = 1;
10119   int ret;
10120
10121   /* Parse args required to build the message */
10122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10123     {
10124       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10125         rx_sw_if_index_set = 1;
10126       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10127         tx_sw_if_index_set = 1;
10128       else if (unformat (i, "rx"))
10129         {
10130           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10131             {
10132               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10133                             &rx_sw_if_index))
10134                 rx_sw_if_index_set = 1;
10135             }
10136           else
10137             break;
10138         }
10139       else if (unformat (i, "tx"))
10140         {
10141           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10142             {
10143               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10144                             &tx_sw_if_index))
10145                 tx_sw_if_index_set = 1;
10146             }
10147           else
10148             break;
10149         }
10150       else if (unformat (i, "del"))
10151         is_add = 0;
10152       else
10153         break;
10154     }
10155
10156   if (rx_sw_if_index_set == 0)
10157     {
10158       errmsg ("missing rx interface name or rx_sw_if_index");
10159       return -99;
10160     }
10161
10162   if (tx_sw_if_index_set == 0)
10163     {
10164       errmsg ("missing tx interface name or tx_sw_if_index");
10165       return -99;
10166     }
10167
10168   M (L2_PATCH_ADD_DEL, mp);
10169
10170   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10171   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10172   mp->is_add = is_add;
10173
10174   S (mp);
10175   W (ret);
10176   return ret;
10177 }
10178
10179 u8 is_del;
10180 u8 localsid_addr[16];
10181 u8 end_psp;
10182 u8 behavior;
10183 u32 sw_if_index;
10184 u32 vlan_index;
10185 u32 fib_table;
10186 u8 nh_addr[16];
10187
10188 static int
10189 api_sr_localsid_add_del (vat_main_t * vam)
10190 {
10191   unformat_input_t *i = vam->input;
10192   vl_api_sr_localsid_add_del_t *mp;
10193
10194   u8 is_del;
10195   ip6_address_t localsid;
10196   u8 end_psp = 0;
10197   u8 behavior = ~0;
10198   u32 sw_if_index;
10199   u32 fib_table = ~(u32) 0;
10200   ip6_address_t nh_addr6;
10201   ip4_address_t nh_addr4;
10202   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10203   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10204
10205   bool nexthop_set = 0;
10206
10207   int ret;
10208
10209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10210     {
10211       if (unformat (i, "del"))
10212         is_del = 1;
10213       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10214       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10215         nexthop_set = 1;
10216       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10217         nexthop_set = 1;
10218       else if (unformat (i, "behavior %u", &behavior));
10219       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10220       else if (unformat (i, "fib-table %u", &fib_table));
10221       else if (unformat (i, "end.psp %u", &behavior));
10222       else
10223         break;
10224     }
10225
10226   M (SR_LOCALSID_ADD_DEL, mp);
10227
10228   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10229   if (nexthop_set)
10230     {
10231       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10232       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10233     }
10234   mp->behavior = behavior;
10235   mp->sw_if_index = ntohl (sw_if_index);
10236   mp->fib_table = ntohl (fib_table);
10237   mp->end_psp = end_psp;
10238   mp->is_del = is_del;
10239
10240   S (mp);
10241   W (ret);
10242   return ret;
10243 }
10244
10245 static int
10246 api_ioam_enable (vat_main_t * vam)
10247 {
10248   unformat_input_t *input = vam->input;
10249   vl_api_ioam_enable_t *mp;
10250   u32 id = 0;
10251   int has_trace_option = 0;
10252   int has_pot_option = 0;
10253   int has_seqno_option = 0;
10254   int has_analyse_option = 0;
10255   int ret;
10256
10257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10258     {
10259       if (unformat (input, "trace"))
10260         has_trace_option = 1;
10261       else if (unformat (input, "pot"))
10262         has_pot_option = 1;
10263       else if (unformat (input, "seqno"))
10264         has_seqno_option = 1;
10265       else if (unformat (input, "analyse"))
10266         has_analyse_option = 1;
10267       else
10268         break;
10269     }
10270   M (IOAM_ENABLE, mp);
10271   mp->id = htons (id);
10272   mp->seqno = has_seqno_option;
10273   mp->analyse = has_analyse_option;
10274   mp->pot_enable = has_pot_option;
10275   mp->trace_enable = has_trace_option;
10276
10277   S (mp);
10278   W (ret);
10279   return ret;
10280 }
10281
10282
10283 static int
10284 api_ioam_disable (vat_main_t * vam)
10285 {
10286   vl_api_ioam_disable_t *mp;
10287   int ret;
10288
10289   M (IOAM_DISABLE, mp);
10290   S (mp);
10291   W (ret);
10292   return ret;
10293 }
10294
10295 #define foreach_tcp_proto_field                 \
10296 _(src_port)                                     \
10297 _(dst_port)
10298
10299 #define foreach_udp_proto_field                 \
10300 _(src_port)                                     \
10301 _(dst_port)
10302
10303 #define foreach_ip4_proto_field                 \
10304 _(src_address)                                  \
10305 _(dst_address)                                  \
10306 _(tos)                                          \
10307 _(length)                                       \
10308 _(fragment_id)                                  \
10309 _(ttl)                                          \
10310 _(protocol)                                     \
10311 _(checksum)
10312
10313 typedef struct
10314 {
10315   u16 src_port, dst_port;
10316 } tcpudp_header_t;
10317
10318 #if VPP_API_TEST_BUILTIN == 0
10319 uword
10320 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10321 {
10322   u8 **maskp = va_arg (*args, u8 **);
10323   u8 *mask = 0;
10324   u8 found_something = 0;
10325   tcp_header_t *tcp;
10326
10327 #define _(a) u8 a=0;
10328   foreach_tcp_proto_field;
10329 #undef _
10330
10331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10332     {
10333       if (0);
10334 #define _(a) else if (unformat (input, #a)) a=1;
10335       foreach_tcp_proto_field
10336 #undef _
10337         else
10338         break;
10339     }
10340
10341 #define _(a) found_something += a;
10342   foreach_tcp_proto_field;
10343 #undef _
10344
10345   if (found_something == 0)
10346     return 0;
10347
10348   vec_validate (mask, sizeof (*tcp) - 1);
10349
10350   tcp = (tcp_header_t *) mask;
10351
10352 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10353   foreach_tcp_proto_field;
10354 #undef _
10355
10356   *maskp = mask;
10357   return 1;
10358 }
10359
10360 uword
10361 unformat_udp_mask (unformat_input_t * input, va_list * args)
10362 {
10363   u8 **maskp = va_arg (*args, u8 **);
10364   u8 *mask = 0;
10365   u8 found_something = 0;
10366   udp_header_t *udp;
10367
10368 #define _(a) u8 a=0;
10369   foreach_udp_proto_field;
10370 #undef _
10371
10372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10373     {
10374       if (0);
10375 #define _(a) else if (unformat (input, #a)) a=1;
10376       foreach_udp_proto_field
10377 #undef _
10378         else
10379         break;
10380     }
10381
10382 #define _(a) found_something += a;
10383   foreach_udp_proto_field;
10384 #undef _
10385
10386   if (found_something == 0)
10387     return 0;
10388
10389   vec_validate (mask, sizeof (*udp) - 1);
10390
10391   udp = (udp_header_t *) mask;
10392
10393 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10394   foreach_udp_proto_field;
10395 #undef _
10396
10397   *maskp = mask;
10398   return 1;
10399 }
10400
10401 uword
10402 unformat_l4_mask (unformat_input_t * input, va_list * args)
10403 {
10404   u8 **maskp = va_arg (*args, u8 **);
10405   u16 src_port = 0, dst_port = 0;
10406   tcpudp_header_t *tcpudp;
10407
10408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10411         return 1;
10412       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10413         return 1;
10414       else if (unformat (input, "src_port"))
10415         src_port = 0xFFFF;
10416       else if (unformat (input, "dst_port"))
10417         dst_port = 0xFFFF;
10418       else
10419         return 0;
10420     }
10421
10422   if (!src_port && !dst_port)
10423     return 0;
10424
10425   u8 *mask = 0;
10426   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10427
10428   tcpudp = (tcpudp_header_t *) mask;
10429   tcpudp->src_port = src_port;
10430   tcpudp->dst_port = dst_port;
10431
10432   *maskp = mask;
10433
10434   return 1;
10435 }
10436
10437 uword
10438 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10439 {
10440   u8 **maskp = va_arg (*args, u8 **);
10441   u8 *mask = 0;
10442   u8 found_something = 0;
10443   ip4_header_t *ip;
10444
10445 #define _(a) u8 a=0;
10446   foreach_ip4_proto_field;
10447 #undef _
10448   u8 version = 0;
10449   u8 hdr_length = 0;
10450
10451
10452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10453     {
10454       if (unformat (input, "version"))
10455         version = 1;
10456       else if (unformat (input, "hdr_length"))
10457         hdr_length = 1;
10458       else if (unformat (input, "src"))
10459         src_address = 1;
10460       else if (unformat (input, "dst"))
10461         dst_address = 1;
10462       else if (unformat (input, "proto"))
10463         protocol = 1;
10464
10465 #define _(a) else if (unformat (input, #a)) a=1;
10466       foreach_ip4_proto_field
10467 #undef _
10468         else
10469         break;
10470     }
10471
10472 #define _(a) found_something += a;
10473   foreach_ip4_proto_field;
10474 #undef _
10475
10476   if (found_something == 0)
10477     return 0;
10478
10479   vec_validate (mask, sizeof (*ip) - 1);
10480
10481   ip = (ip4_header_t *) mask;
10482
10483 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10484   foreach_ip4_proto_field;
10485 #undef _
10486
10487   ip->ip_version_and_header_length = 0;
10488
10489   if (version)
10490     ip->ip_version_and_header_length |= 0xF0;
10491
10492   if (hdr_length)
10493     ip->ip_version_and_header_length |= 0x0F;
10494
10495   *maskp = mask;
10496   return 1;
10497 }
10498
10499 #define foreach_ip6_proto_field                 \
10500 _(src_address)                                  \
10501 _(dst_address)                                  \
10502 _(payload_length)                               \
10503 _(hop_limit)                                    \
10504 _(protocol)
10505
10506 uword
10507 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10508 {
10509   u8 **maskp = va_arg (*args, u8 **);
10510   u8 *mask = 0;
10511   u8 found_something = 0;
10512   ip6_header_t *ip;
10513   u32 ip_version_traffic_class_and_flow_label;
10514
10515 #define _(a) u8 a=0;
10516   foreach_ip6_proto_field;
10517 #undef _
10518   u8 version = 0;
10519   u8 traffic_class = 0;
10520   u8 flow_label = 0;
10521
10522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10523     {
10524       if (unformat (input, "version"))
10525         version = 1;
10526       else if (unformat (input, "traffic-class"))
10527         traffic_class = 1;
10528       else if (unformat (input, "flow-label"))
10529         flow_label = 1;
10530       else if (unformat (input, "src"))
10531         src_address = 1;
10532       else if (unformat (input, "dst"))
10533         dst_address = 1;
10534       else if (unformat (input, "proto"))
10535         protocol = 1;
10536
10537 #define _(a) else if (unformat (input, #a)) a=1;
10538       foreach_ip6_proto_field
10539 #undef _
10540         else
10541         break;
10542     }
10543
10544 #define _(a) found_something += a;
10545   foreach_ip6_proto_field;
10546 #undef _
10547
10548   if (found_something == 0)
10549     return 0;
10550
10551   vec_validate (mask, sizeof (*ip) - 1);
10552
10553   ip = (ip6_header_t *) mask;
10554
10555 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10556   foreach_ip6_proto_field;
10557 #undef _
10558
10559   ip_version_traffic_class_and_flow_label = 0;
10560
10561   if (version)
10562     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10563
10564   if (traffic_class)
10565     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10566
10567   if (flow_label)
10568     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10569
10570   ip->ip_version_traffic_class_and_flow_label =
10571     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10572
10573   *maskp = mask;
10574   return 1;
10575 }
10576
10577 uword
10578 unformat_l3_mask (unformat_input_t * input, va_list * args)
10579 {
10580   u8 **maskp = va_arg (*args, u8 **);
10581
10582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10583     {
10584       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10585         return 1;
10586       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10587         return 1;
10588       else
10589         break;
10590     }
10591   return 0;
10592 }
10593
10594 uword
10595 unformat_l2_mask (unformat_input_t * input, va_list * args)
10596 {
10597   u8 **maskp = va_arg (*args, u8 **);
10598   u8 *mask = 0;
10599   u8 src = 0;
10600   u8 dst = 0;
10601   u8 proto = 0;
10602   u8 tag1 = 0;
10603   u8 tag2 = 0;
10604   u8 ignore_tag1 = 0;
10605   u8 ignore_tag2 = 0;
10606   u8 cos1 = 0;
10607   u8 cos2 = 0;
10608   u8 dot1q = 0;
10609   u8 dot1ad = 0;
10610   int len = 14;
10611
10612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10613     {
10614       if (unformat (input, "src"))
10615         src = 1;
10616       else if (unformat (input, "dst"))
10617         dst = 1;
10618       else if (unformat (input, "proto"))
10619         proto = 1;
10620       else if (unformat (input, "tag1"))
10621         tag1 = 1;
10622       else if (unformat (input, "tag2"))
10623         tag2 = 1;
10624       else if (unformat (input, "ignore-tag1"))
10625         ignore_tag1 = 1;
10626       else if (unformat (input, "ignore-tag2"))
10627         ignore_tag2 = 1;
10628       else if (unformat (input, "cos1"))
10629         cos1 = 1;
10630       else if (unformat (input, "cos2"))
10631         cos2 = 1;
10632       else if (unformat (input, "dot1q"))
10633         dot1q = 1;
10634       else if (unformat (input, "dot1ad"))
10635         dot1ad = 1;
10636       else
10637         break;
10638     }
10639   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10640        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10641     return 0;
10642
10643   if (tag1 || ignore_tag1 || cos1 || dot1q)
10644     len = 18;
10645   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10646     len = 22;
10647
10648   vec_validate (mask, len - 1);
10649
10650   if (dst)
10651     clib_memset (mask, 0xff, 6);
10652
10653   if (src)
10654     clib_memset (mask + 6, 0xff, 6);
10655
10656   if (tag2 || dot1ad)
10657     {
10658       /* inner vlan tag */
10659       if (tag2)
10660         {
10661           mask[19] = 0xff;
10662           mask[18] = 0x0f;
10663         }
10664       if (cos2)
10665         mask[18] |= 0xe0;
10666       if (proto)
10667         mask[21] = mask[20] = 0xff;
10668       if (tag1)
10669         {
10670           mask[15] = 0xff;
10671           mask[14] = 0x0f;
10672         }
10673       if (cos1)
10674         mask[14] |= 0xe0;
10675       *maskp = mask;
10676       return 1;
10677     }
10678   if (tag1 | dot1q)
10679     {
10680       if (tag1)
10681         {
10682           mask[15] = 0xff;
10683           mask[14] = 0x0f;
10684         }
10685       if (cos1)
10686         mask[14] |= 0xe0;
10687       if (proto)
10688         mask[16] = mask[17] = 0xff;
10689
10690       *maskp = mask;
10691       return 1;
10692     }
10693   if (cos2)
10694     mask[18] |= 0xe0;
10695   if (cos1)
10696     mask[14] |= 0xe0;
10697   if (proto)
10698     mask[12] = mask[13] = 0xff;
10699
10700   *maskp = mask;
10701   return 1;
10702 }
10703
10704 uword
10705 unformat_classify_mask (unformat_input_t * input, va_list * args)
10706 {
10707   u8 **maskp = va_arg (*args, u8 **);
10708   u32 *skipp = va_arg (*args, u32 *);
10709   u32 *matchp = va_arg (*args, u32 *);
10710   u32 match;
10711   u8 *mask = 0;
10712   u8 *l2 = 0;
10713   u8 *l3 = 0;
10714   u8 *l4 = 0;
10715   int i;
10716
10717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10720         ;
10721       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10722         ;
10723       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10724         ;
10725       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10726         ;
10727       else
10728         break;
10729     }
10730
10731   if (l4 && !l3)
10732     {
10733       vec_free (mask);
10734       vec_free (l2);
10735       vec_free (l4);
10736       return 0;
10737     }
10738
10739   if (mask || l2 || l3 || l4)
10740     {
10741       if (l2 || l3 || l4)
10742         {
10743           /* "With a free Ethernet header in every package" */
10744           if (l2 == 0)
10745             vec_validate (l2, 13);
10746           mask = l2;
10747           if (vec_len (l3))
10748             {
10749               vec_append (mask, l3);
10750               vec_free (l3);
10751             }
10752           if (vec_len (l4))
10753             {
10754               vec_append (mask, l4);
10755               vec_free (l4);
10756             }
10757         }
10758
10759       /* Scan forward looking for the first significant mask octet */
10760       for (i = 0; i < vec_len (mask); i++)
10761         if (mask[i])
10762           break;
10763
10764       /* compute (skip, match) params */
10765       *skipp = i / sizeof (u32x4);
10766       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10767
10768       /* Pad mask to an even multiple of the vector size */
10769       while (vec_len (mask) % sizeof (u32x4))
10770         vec_add1 (mask, 0);
10771
10772       match = vec_len (mask) / sizeof (u32x4);
10773
10774       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10775         {
10776           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10777           if (*tmp || *(tmp + 1))
10778             break;
10779           match--;
10780         }
10781       if (match == 0)
10782         clib_warning ("BUG: match 0");
10783
10784       _vec_len (mask) = match * sizeof (u32x4);
10785
10786       *matchp = match;
10787       *maskp = mask;
10788
10789       return 1;
10790     }
10791
10792   return 0;
10793 }
10794 #endif /* VPP_API_TEST_BUILTIN */
10795
10796 #define foreach_l2_next                         \
10797 _(drop, DROP)                                   \
10798 _(ethernet, ETHERNET_INPUT)                     \
10799 _(ip4, IP4_INPUT)                               \
10800 _(ip6, IP6_INPUT)
10801
10802 uword
10803 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10804 {
10805   u32 *miss_next_indexp = va_arg (*args, u32 *);
10806   u32 next_index = 0;
10807   u32 tmp;
10808
10809 #define _(n,N) \
10810   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10811   foreach_l2_next;
10812 #undef _
10813
10814   if (unformat (input, "%d", &tmp))
10815     {
10816       next_index = tmp;
10817       goto out;
10818     }
10819
10820   return 0;
10821
10822 out:
10823   *miss_next_indexp = next_index;
10824   return 1;
10825 }
10826
10827 #define foreach_ip_next                         \
10828 _(drop, DROP)                                   \
10829 _(local, LOCAL)                                 \
10830 _(rewrite, REWRITE)
10831
10832 uword
10833 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10834 {
10835   u32 *miss_next_indexp = va_arg (*args, u32 *);
10836   u32 next_index = 0;
10837   u32 tmp;
10838
10839 #define _(n,N) \
10840   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10841   foreach_ip_next;
10842 #undef _
10843
10844   if (unformat (input, "%d", &tmp))
10845     {
10846       next_index = tmp;
10847       goto out;
10848     }
10849
10850   return 0;
10851
10852 out:
10853   *miss_next_indexp = next_index;
10854   return 1;
10855 }
10856
10857 #define foreach_acl_next                        \
10858 _(deny, DENY)
10859
10860 uword
10861 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10862 {
10863   u32 *miss_next_indexp = va_arg (*args, u32 *);
10864   u32 next_index = 0;
10865   u32 tmp;
10866
10867 #define _(n,N) \
10868   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10869   foreach_acl_next;
10870 #undef _
10871
10872   if (unformat (input, "permit"))
10873     {
10874       next_index = ~0;
10875       goto out;
10876     }
10877   else if (unformat (input, "%d", &tmp))
10878     {
10879       next_index = tmp;
10880       goto out;
10881     }
10882
10883   return 0;
10884
10885 out:
10886   *miss_next_indexp = next_index;
10887   return 1;
10888 }
10889
10890 uword
10891 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10892 {
10893   u32 *r = va_arg (*args, u32 *);
10894
10895   if (unformat (input, "conform-color"))
10896     *r = POLICE_CONFORM;
10897   else if (unformat (input, "exceed-color"))
10898     *r = POLICE_EXCEED;
10899   else
10900     return 0;
10901
10902   return 1;
10903 }
10904
10905 static int
10906 api_classify_add_del_table (vat_main_t * vam)
10907 {
10908   unformat_input_t *i = vam->input;
10909   vl_api_classify_add_del_table_t *mp;
10910
10911   u32 nbuckets = 2;
10912   u32 skip = ~0;
10913   u32 match = ~0;
10914   int is_add = 1;
10915   int del_chain = 0;
10916   u32 table_index = ~0;
10917   u32 next_table_index = ~0;
10918   u32 miss_next_index = ~0;
10919   u32 memory_size = 32 << 20;
10920   u8 *mask = 0;
10921   u32 current_data_flag = 0;
10922   int current_data_offset = 0;
10923   int ret;
10924
10925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10926     {
10927       if (unformat (i, "del"))
10928         is_add = 0;
10929       else if (unformat (i, "del-chain"))
10930         {
10931           is_add = 0;
10932           del_chain = 1;
10933         }
10934       else if (unformat (i, "buckets %d", &nbuckets))
10935         ;
10936       else if (unformat (i, "memory_size %d", &memory_size))
10937         ;
10938       else if (unformat (i, "skip %d", &skip))
10939         ;
10940       else if (unformat (i, "match %d", &match))
10941         ;
10942       else if (unformat (i, "table %d", &table_index))
10943         ;
10944       else if (unformat (i, "mask %U", unformat_classify_mask,
10945                          &mask, &skip, &match))
10946         ;
10947       else if (unformat (i, "next-table %d", &next_table_index))
10948         ;
10949       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10950                          &miss_next_index))
10951         ;
10952       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10953                          &miss_next_index))
10954         ;
10955       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10956                          &miss_next_index))
10957         ;
10958       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10959         ;
10960       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10961         ;
10962       else
10963         break;
10964     }
10965
10966   if (is_add && mask == 0)
10967     {
10968       errmsg ("Mask required");
10969       return -99;
10970     }
10971
10972   if (is_add && skip == ~0)
10973     {
10974       errmsg ("skip count required");
10975       return -99;
10976     }
10977
10978   if (is_add && match == ~0)
10979     {
10980       errmsg ("match count required");
10981       return -99;
10982     }
10983
10984   if (!is_add && table_index == ~0)
10985     {
10986       errmsg ("table index required for delete");
10987       return -99;
10988     }
10989
10990   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10991
10992   mp->is_add = is_add;
10993   mp->del_chain = del_chain;
10994   mp->table_index = ntohl (table_index);
10995   mp->nbuckets = ntohl (nbuckets);
10996   mp->memory_size = ntohl (memory_size);
10997   mp->skip_n_vectors = ntohl (skip);
10998   mp->match_n_vectors = ntohl (match);
10999   mp->next_table_index = ntohl (next_table_index);
11000   mp->miss_next_index = ntohl (miss_next_index);
11001   mp->current_data_flag = ntohl (current_data_flag);
11002   mp->current_data_offset = ntohl (current_data_offset);
11003   mp->mask_len = ntohl (vec_len (mask));
11004   clib_memcpy (mp->mask, mask, vec_len (mask));
11005
11006   vec_free (mask);
11007
11008   S (mp);
11009   W (ret);
11010   return ret;
11011 }
11012
11013 #if VPP_API_TEST_BUILTIN == 0
11014 uword
11015 unformat_l4_match (unformat_input_t * input, va_list * args)
11016 {
11017   u8 **matchp = va_arg (*args, u8 **);
11018
11019   u8 *proto_header = 0;
11020   int src_port = 0;
11021   int dst_port = 0;
11022
11023   tcpudp_header_t h;
11024
11025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11026     {
11027       if (unformat (input, "src_port %d", &src_port))
11028         ;
11029       else if (unformat (input, "dst_port %d", &dst_port))
11030         ;
11031       else
11032         return 0;
11033     }
11034
11035   h.src_port = clib_host_to_net_u16 (src_port);
11036   h.dst_port = clib_host_to_net_u16 (dst_port);
11037   vec_validate (proto_header, sizeof (h) - 1);
11038   memcpy (proto_header, &h, sizeof (h));
11039
11040   *matchp = proto_header;
11041
11042   return 1;
11043 }
11044
11045 uword
11046 unformat_ip4_match (unformat_input_t * input, va_list * args)
11047 {
11048   u8 **matchp = va_arg (*args, u8 **);
11049   u8 *match = 0;
11050   ip4_header_t *ip;
11051   int version = 0;
11052   u32 version_val;
11053   int hdr_length = 0;
11054   u32 hdr_length_val;
11055   int src = 0, dst = 0;
11056   ip4_address_t src_val, dst_val;
11057   int proto = 0;
11058   u32 proto_val;
11059   int tos = 0;
11060   u32 tos_val;
11061   int length = 0;
11062   u32 length_val;
11063   int fragment_id = 0;
11064   u32 fragment_id_val;
11065   int ttl = 0;
11066   int ttl_val;
11067   int checksum = 0;
11068   u32 checksum_val;
11069
11070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (input, "version %d", &version_val))
11073         version = 1;
11074       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11075         hdr_length = 1;
11076       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11077         src = 1;
11078       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11079         dst = 1;
11080       else if (unformat (input, "proto %d", &proto_val))
11081         proto = 1;
11082       else if (unformat (input, "tos %d", &tos_val))
11083         tos = 1;
11084       else if (unformat (input, "length %d", &length_val))
11085         length = 1;
11086       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11087         fragment_id = 1;
11088       else if (unformat (input, "ttl %d", &ttl_val))
11089         ttl = 1;
11090       else if (unformat (input, "checksum %d", &checksum_val))
11091         checksum = 1;
11092       else
11093         break;
11094     }
11095
11096   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11097       + ttl + checksum == 0)
11098     return 0;
11099
11100   /*
11101    * Aligned because we use the real comparison functions
11102    */
11103   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11104
11105   ip = (ip4_header_t *) match;
11106
11107   /* These are realistically matched in practice */
11108   if (src)
11109     ip->src_address.as_u32 = src_val.as_u32;
11110
11111   if (dst)
11112     ip->dst_address.as_u32 = dst_val.as_u32;
11113
11114   if (proto)
11115     ip->protocol = proto_val;
11116
11117
11118   /* These are not, but they're included for completeness */
11119   if (version)
11120     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11121
11122   if (hdr_length)
11123     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11124
11125   if (tos)
11126     ip->tos = tos_val;
11127
11128   if (length)
11129     ip->length = clib_host_to_net_u16 (length_val);
11130
11131   if (ttl)
11132     ip->ttl = ttl_val;
11133
11134   if (checksum)
11135     ip->checksum = clib_host_to_net_u16 (checksum_val);
11136
11137   *matchp = match;
11138   return 1;
11139 }
11140
11141 uword
11142 unformat_ip6_match (unformat_input_t * input, va_list * args)
11143 {
11144   u8 **matchp = va_arg (*args, u8 **);
11145   u8 *match = 0;
11146   ip6_header_t *ip;
11147   int version = 0;
11148   u32 version_val;
11149   u8 traffic_class = 0;
11150   u32 traffic_class_val = 0;
11151   u8 flow_label = 0;
11152   u8 flow_label_val;
11153   int src = 0, dst = 0;
11154   ip6_address_t src_val, dst_val;
11155   int proto = 0;
11156   u32 proto_val;
11157   int payload_length = 0;
11158   u32 payload_length_val;
11159   int hop_limit = 0;
11160   int hop_limit_val;
11161   u32 ip_version_traffic_class_and_flow_label;
11162
11163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11164     {
11165       if (unformat (input, "version %d", &version_val))
11166         version = 1;
11167       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11168         traffic_class = 1;
11169       else if (unformat (input, "flow_label %d", &flow_label_val))
11170         flow_label = 1;
11171       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11172         src = 1;
11173       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11174         dst = 1;
11175       else if (unformat (input, "proto %d", &proto_val))
11176         proto = 1;
11177       else if (unformat (input, "payload_length %d", &payload_length_val))
11178         payload_length = 1;
11179       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11180         hop_limit = 1;
11181       else
11182         break;
11183     }
11184
11185   if (version + traffic_class + flow_label + src + dst + proto +
11186       payload_length + hop_limit == 0)
11187     return 0;
11188
11189   /*
11190    * Aligned because we use the real comparison functions
11191    */
11192   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11193
11194   ip = (ip6_header_t *) match;
11195
11196   if (src)
11197     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11198
11199   if (dst)
11200     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11201
11202   if (proto)
11203     ip->protocol = proto_val;
11204
11205   ip_version_traffic_class_and_flow_label = 0;
11206
11207   if (version)
11208     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11209
11210   if (traffic_class)
11211     ip_version_traffic_class_and_flow_label |=
11212       (traffic_class_val & 0xFF) << 20;
11213
11214   if (flow_label)
11215     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11216
11217   ip->ip_version_traffic_class_and_flow_label =
11218     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11219
11220   if (payload_length)
11221     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11222
11223   if (hop_limit)
11224     ip->hop_limit = hop_limit_val;
11225
11226   *matchp = match;
11227   return 1;
11228 }
11229
11230 uword
11231 unformat_l3_match (unformat_input_t * input, va_list * args)
11232 {
11233   u8 **matchp = va_arg (*args, u8 **);
11234
11235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11236     {
11237       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11238         return 1;
11239       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11240         return 1;
11241       else
11242         break;
11243     }
11244   return 0;
11245 }
11246
11247 uword
11248 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11249 {
11250   u8 *tagp = va_arg (*args, u8 *);
11251   u32 tag;
11252
11253   if (unformat (input, "%d", &tag))
11254     {
11255       tagp[0] = (tag >> 8) & 0x0F;
11256       tagp[1] = tag & 0xFF;
11257       return 1;
11258     }
11259
11260   return 0;
11261 }
11262
11263 uword
11264 unformat_l2_match (unformat_input_t * input, va_list * args)
11265 {
11266   u8 **matchp = va_arg (*args, u8 **);
11267   u8 *match = 0;
11268   u8 src = 0;
11269   u8 src_val[6];
11270   u8 dst = 0;
11271   u8 dst_val[6];
11272   u8 proto = 0;
11273   u16 proto_val;
11274   u8 tag1 = 0;
11275   u8 tag1_val[2];
11276   u8 tag2 = 0;
11277   u8 tag2_val[2];
11278   int len = 14;
11279   u8 ignore_tag1 = 0;
11280   u8 ignore_tag2 = 0;
11281   u8 cos1 = 0;
11282   u8 cos2 = 0;
11283   u32 cos1_val = 0;
11284   u32 cos2_val = 0;
11285
11286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11287     {
11288       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11289         src = 1;
11290       else
11291         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11292         dst = 1;
11293       else if (unformat (input, "proto %U",
11294                          unformat_ethernet_type_host_byte_order, &proto_val))
11295         proto = 1;
11296       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11297         tag1 = 1;
11298       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11299         tag2 = 1;
11300       else if (unformat (input, "ignore-tag1"))
11301         ignore_tag1 = 1;
11302       else if (unformat (input, "ignore-tag2"))
11303         ignore_tag2 = 1;
11304       else if (unformat (input, "cos1 %d", &cos1_val))
11305         cos1 = 1;
11306       else if (unformat (input, "cos2 %d", &cos2_val))
11307         cos2 = 1;
11308       else
11309         break;
11310     }
11311   if ((src + dst + proto + tag1 + tag2 +
11312        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11313     return 0;
11314
11315   if (tag1 || ignore_tag1 || cos1)
11316     len = 18;
11317   if (tag2 || ignore_tag2 || cos2)
11318     len = 22;
11319
11320   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11321
11322   if (dst)
11323     clib_memcpy (match, dst_val, 6);
11324
11325   if (src)
11326     clib_memcpy (match + 6, src_val, 6);
11327
11328   if (tag2)
11329     {
11330       /* inner vlan tag */
11331       match[19] = tag2_val[1];
11332       match[18] = tag2_val[0];
11333       if (cos2)
11334         match[18] |= (cos2_val & 0x7) << 5;
11335       if (proto)
11336         {
11337           match[21] = proto_val & 0xff;
11338           match[20] = proto_val >> 8;
11339         }
11340       if (tag1)
11341         {
11342           match[15] = tag1_val[1];
11343           match[14] = tag1_val[0];
11344         }
11345       if (cos1)
11346         match[14] |= (cos1_val & 0x7) << 5;
11347       *matchp = match;
11348       return 1;
11349     }
11350   if (tag1)
11351     {
11352       match[15] = tag1_val[1];
11353       match[14] = tag1_val[0];
11354       if (proto)
11355         {
11356           match[17] = proto_val & 0xff;
11357           match[16] = proto_val >> 8;
11358         }
11359       if (cos1)
11360         match[14] |= (cos1_val & 0x7) << 5;
11361
11362       *matchp = match;
11363       return 1;
11364     }
11365   if (cos2)
11366     match[18] |= (cos2_val & 0x7) << 5;
11367   if (cos1)
11368     match[14] |= (cos1_val & 0x7) << 5;
11369   if (proto)
11370     {
11371       match[13] = proto_val & 0xff;
11372       match[12] = proto_val >> 8;
11373     }
11374
11375   *matchp = match;
11376   return 1;
11377 }
11378
11379 uword
11380 unformat_qos_source (unformat_input_t * input, va_list * args)
11381 {
11382   int *qs = va_arg (*args, int *);
11383
11384   if (unformat (input, "ip"))
11385     *qs = QOS_SOURCE_IP;
11386   else if (unformat (input, "mpls"))
11387     *qs = QOS_SOURCE_MPLS;
11388   else if (unformat (input, "ext"))
11389     *qs = QOS_SOURCE_EXT;
11390   else if (unformat (input, "vlan"))
11391     *qs = QOS_SOURCE_VLAN;
11392   else
11393     return 0;
11394
11395   return 1;
11396 }
11397 #endif
11398
11399 uword
11400 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11401 {
11402   u8 **matchp = va_arg (*args, u8 **);
11403   u32 skip_n_vectors = va_arg (*args, u32);
11404   u32 match_n_vectors = va_arg (*args, u32);
11405
11406   u8 *match = 0;
11407   u8 *l2 = 0;
11408   u8 *l3 = 0;
11409   u8 *l4 = 0;
11410
11411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11412     {
11413       if (unformat (input, "hex %U", unformat_hex_string, &match))
11414         ;
11415       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11416         ;
11417       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11418         ;
11419       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11420         ;
11421       else
11422         break;
11423     }
11424
11425   if (l4 && !l3)
11426     {
11427       vec_free (match);
11428       vec_free (l2);
11429       vec_free (l4);
11430       return 0;
11431     }
11432
11433   if (match || l2 || l3 || l4)
11434     {
11435       if (l2 || l3 || l4)
11436         {
11437           /* "Win a free Ethernet header in every packet" */
11438           if (l2 == 0)
11439             vec_validate_aligned (l2, 13, sizeof (u32x4));
11440           match = l2;
11441           if (vec_len (l3))
11442             {
11443               vec_append_aligned (match, l3, sizeof (u32x4));
11444               vec_free (l3);
11445             }
11446           if (vec_len (l4))
11447             {
11448               vec_append_aligned (match, l4, sizeof (u32x4));
11449               vec_free (l4);
11450             }
11451         }
11452
11453       /* Make sure the vector is big enough even if key is all 0's */
11454       vec_validate_aligned
11455         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11456          sizeof (u32x4));
11457
11458       /* Set size, include skipped vectors */
11459       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11460
11461       *matchp = match;
11462
11463       return 1;
11464     }
11465
11466   return 0;
11467 }
11468
11469 static int
11470 api_classify_add_del_session (vat_main_t * vam)
11471 {
11472   unformat_input_t *i = vam->input;
11473   vl_api_classify_add_del_session_t *mp;
11474   int is_add = 1;
11475   u32 table_index = ~0;
11476   u32 hit_next_index = ~0;
11477   u32 opaque_index = ~0;
11478   u8 *match = 0;
11479   i32 advance = 0;
11480   u32 skip_n_vectors = 0;
11481   u32 match_n_vectors = 0;
11482   u32 action = 0;
11483   u32 metadata = 0;
11484   int ret;
11485
11486   /*
11487    * Warning: you have to supply skip_n and match_n
11488    * because the API client cant simply look at the classify
11489    * table object.
11490    */
11491
11492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11493     {
11494       if (unformat (i, "del"))
11495         is_add = 0;
11496       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11497                          &hit_next_index))
11498         ;
11499       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11500                          &hit_next_index))
11501         ;
11502       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11503                          &hit_next_index))
11504         ;
11505       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11506         ;
11507       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11508         ;
11509       else if (unformat (i, "opaque-index %d", &opaque_index))
11510         ;
11511       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11512         ;
11513       else if (unformat (i, "match_n %d", &match_n_vectors))
11514         ;
11515       else if (unformat (i, "match %U", api_unformat_classify_match,
11516                          &match, skip_n_vectors, match_n_vectors))
11517         ;
11518       else if (unformat (i, "advance %d", &advance))
11519         ;
11520       else if (unformat (i, "table-index %d", &table_index))
11521         ;
11522       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11523         action = 1;
11524       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11525         action = 2;
11526       else if (unformat (i, "action %d", &action))
11527         ;
11528       else if (unformat (i, "metadata %d", &metadata))
11529         ;
11530       else
11531         break;
11532     }
11533
11534   if (table_index == ~0)
11535     {
11536       errmsg ("Table index required");
11537       return -99;
11538     }
11539
11540   if (is_add && match == 0)
11541     {
11542       errmsg ("Match value required");
11543       return -99;
11544     }
11545
11546   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11547
11548   mp->is_add = is_add;
11549   mp->table_index = ntohl (table_index);
11550   mp->hit_next_index = ntohl (hit_next_index);
11551   mp->opaque_index = ntohl (opaque_index);
11552   mp->advance = ntohl (advance);
11553   mp->action = action;
11554   mp->metadata = ntohl (metadata);
11555   mp->match_len = ntohl (vec_len (match));
11556   clib_memcpy (mp->match, match, vec_len (match));
11557   vec_free (match);
11558
11559   S (mp);
11560   W (ret);
11561   return ret;
11562 }
11563
11564 static int
11565 api_classify_set_interface_ip_table (vat_main_t * vam)
11566 {
11567   unformat_input_t *i = vam->input;
11568   vl_api_classify_set_interface_ip_table_t *mp;
11569   u32 sw_if_index;
11570   int sw_if_index_set;
11571   u32 table_index = ~0;
11572   u8 is_ipv6 = 0;
11573   int ret;
11574
11575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11576     {
11577       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11578         sw_if_index_set = 1;
11579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11580         sw_if_index_set = 1;
11581       else if (unformat (i, "table %d", &table_index))
11582         ;
11583       else
11584         {
11585           clib_warning ("parse error '%U'", format_unformat_error, i);
11586           return -99;
11587         }
11588     }
11589
11590   if (sw_if_index_set == 0)
11591     {
11592       errmsg ("missing interface name or sw_if_index");
11593       return -99;
11594     }
11595
11596
11597   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11598
11599   mp->sw_if_index = ntohl (sw_if_index);
11600   mp->table_index = ntohl (table_index);
11601   mp->is_ipv6 = is_ipv6;
11602
11603   S (mp);
11604   W (ret);
11605   return ret;
11606 }
11607
11608 static int
11609 api_classify_set_interface_l2_tables (vat_main_t * vam)
11610 {
11611   unformat_input_t *i = vam->input;
11612   vl_api_classify_set_interface_l2_tables_t *mp;
11613   u32 sw_if_index;
11614   int sw_if_index_set;
11615   u32 ip4_table_index = ~0;
11616   u32 ip6_table_index = ~0;
11617   u32 other_table_index = ~0;
11618   u32 is_input = 1;
11619   int ret;
11620
11621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11622     {
11623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11624         sw_if_index_set = 1;
11625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11626         sw_if_index_set = 1;
11627       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11628         ;
11629       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11630         ;
11631       else if (unformat (i, "other-table %d", &other_table_index))
11632         ;
11633       else if (unformat (i, "is-input %d", &is_input))
11634         ;
11635       else
11636         {
11637           clib_warning ("parse error '%U'", format_unformat_error, i);
11638           return -99;
11639         }
11640     }
11641
11642   if (sw_if_index_set == 0)
11643     {
11644       errmsg ("missing interface name or sw_if_index");
11645       return -99;
11646     }
11647
11648
11649   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11650
11651   mp->sw_if_index = ntohl (sw_if_index);
11652   mp->ip4_table_index = ntohl (ip4_table_index);
11653   mp->ip6_table_index = ntohl (ip6_table_index);
11654   mp->other_table_index = ntohl (other_table_index);
11655   mp->is_input = (u8) is_input;
11656
11657   S (mp);
11658   W (ret);
11659   return ret;
11660 }
11661
11662 static int
11663 api_set_ipfix_exporter (vat_main_t * vam)
11664 {
11665   unformat_input_t *i = vam->input;
11666   vl_api_set_ipfix_exporter_t *mp;
11667   ip4_address_t collector_address;
11668   u8 collector_address_set = 0;
11669   u32 collector_port = ~0;
11670   ip4_address_t src_address;
11671   u8 src_address_set = 0;
11672   u32 vrf_id = ~0;
11673   u32 path_mtu = ~0;
11674   u32 template_interval = ~0;
11675   u8 udp_checksum = 0;
11676   int ret;
11677
11678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (i, "collector_address %U", unformat_ip4_address,
11681                     &collector_address))
11682         collector_address_set = 1;
11683       else if (unformat (i, "collector_port %d", &collector_port))
11684         ;
11685       else if (unformat (i, "src_address %U", unformat_ip4_address,
11686                          &src_address))
11687         src_address_set = 1;
11688       else if (unformat (i, "vrf_id %d", &vrf_id))
11689         ;
11690       else if (unformat (i, "path_mtu %d", &path_mtu))
11691         ;
11692       else if (unformat (i, "template_interval %d", &template_interval))
11693         ;
11694       else if (unformat (i, "udp_checksum"))
11695         udp_checksum = 1;
11696       else
11697         break;
11698     }
11699
11700   if (collector_address_set == 0)
11701     {
11702       errmsg ("collector_address required");
11703       return -99;
11704     }
11705
11706   if (src_address_set == 0)
11707     {
11708       errmsg ("src_address required");
11709       return -99;
11710     }
11711
11712   M (SET_IPFIX_EXPORTER, mp);
11713
11714   memcpy (mp->collector_address, collector_address.data,
11715           sizeof (collector_address.data));
11716   mp->collector_port = htons ((u16) collector_port);
11717   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11718   mp->vrf_id = htonl (vrf_id);
11719   mp->path_mtu = htonl (path_mtu);
11720   mp->template_interval = htonl (template_interval);
11721   mp->udp_checksum = udp_checksum;
11722
11723   S (mp);
11724   W (ret);
11725   return ret;
11726 }
11727
11728 static int
11729 api_set_ipfix_classify_stream (vat_main_t * vam)
11730 {
11731   unformat_input_t *i = vam->input;
11732   vl_api_set_ipfix_classify_stream_t *mp;
11733   u32 domain_id = 0;
11734   u32 src_port = UDP_DST_PORT_ipfix;
11735   int ret;
11736
11737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11738     {
11739       if (unformat (i, "domain %d", &domain_id))
11740         ;
11741       else if (unformat (i, "src_port %d", &src_port))
11742         ;
11743       else
11744         {
11745           errmsg ("unknown input `%U'", format_unformat_error, i);
11746           return -99;
11747         }
11748     }
11749
11750   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11751
11752   mp->domain_id = htonl (domain_id);
11753   mp->src_port = htons ((u16) src_port);
11754
11755   S (mp);
11756   W (ret);
11757   return ret;
11758 }
11759
11760 static int
11761 api_ipfix_classify_table_add_del (vat_main_t * vam)
11762 {
11763   unformat_input_t *i = vam->input;
11764   vl_api_ipfix_classify_table_add_del_t *mp;
11765   int is_add = -1;
11766   u32 classify_table_index = ~0;
11767   u8 ip_version = 0;
11768   u8 transport_protocol = 255;
11769   int ret;
11770
11771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11772     {
11773       if (unformat (i, "add"))
11774         is_add = 1;
11775       else if (unformat (i, "del"))
11776         is_add = 0;
11777       else if (unformat (i, "table %d", &classify_table_index))
11778         ;
11779       else if (unformat (i, "ip4"))
11780         ip_version = 4;
11781       else if (unformat (i, "ip6"))
11782         ip_version = 6;
11783       else if (unformat (i, "tcp"))
11784         transport_protocol = 6;
11785       else if (unformat (i, "udp"))
11786         transport_protocol = 17;
11787       else
11788         {
11789           errmsg ("unknown input `%U'", format_unformat_error, i);
11790           return -99;
11791         }
11792     }
11793
11794   if (is_add == -1)
11795     {
11796       errmsg ("expecting: add|del");
11797       return -99;
11798     }
11799   if (classify_table_index == ~0)
11800     {
11801       errmsg ("classifier table not specified");
11802       return -99;
11803     }
11804   if (ip_version == 0)
11805     {
11806       errmsg ("IP version not specified");
11807       return -99;
11808     }
11809
11810   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11811
11812   mp->is_add = is_add;
11813   mp->table_id = htonl (classify_table_index);
11814   mp->ip_version = ip_version;
11815   mp->transport_protocol = transport_protocol;
11816
11817   S (mp);
11818   W (ret);
11819   return ret;
11820 }
11821
11822 static int
11823 api_get_node_index (vat_main_t * vam)
11824 {
11825   unformat_input_t *i = vam->input;
11826   vl_api_get_node_index_t *mp;
11827   u8 *name = 0;
11828   int ret;
11829
11830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11831     {
11832       if (unformat (i, "node %s", &name))
11833         ;
11834       else
11835         break;
11836     }
11837   if (name == 0)
11838     {
11839       errmsg ("node name required");
11840       return -99;
11841     }
11842   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11843     {
11844       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11845       return -99;
11846     }
11847
11848   M (GET_NODE_INDEX, mp);
11849   clib_memcpy (mp->node_name, name, vec_len (name));
11850   vec_free (name);
11851
11852   S (mp);
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static int
11858 api_get_next_index (vat_main_t * vam)
11859 {
11860   unformat_input_t *i = vam->input;
11861   vl_api_get_next_index_t *mp;
11862   u8 *node_name = 0, *next_node_name = 0;
11863   int ret;
11864
11865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11866     {
11867       if (unformat (i, "node-name %s", &node_name))
11868         ;
11869       else if (unformat (i, "next-node-name %s", &next_node_name))
11870         break;
11871     }
11872
11873   if (node_name == 0)
11874     {
11875       errmsg ("node name required");
11876       return -99;
11877     }
11878   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11879     {
11880       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11881       return -99;
11882     }
11883
11884   if (next_node_name == 0)
11885     {
11886       errmsg ("next node name required");
11887       return -99;
11888     }
11889   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11890     {
11891       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11892       return -99;
11893     }
11894
11895   M (GET_NEXT_INDEX, mp);
11896   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11897   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11898   vec_free (node_name);
11899   vec_free (next_node_name);
11900
11901   S (mp);
11902   W (ret);
11903   return ret;
11904 }
11905
11906 static int
11907 api_add_node_next (vat_main_t * vam)
11908 {
11909   unformat_input_t *i = vam->input;
11910   vl_api_add_node_next_t *mp;
11911   u8 *name = 0;
11912   u8 *next = 0;
11913   int ret;
11914
11915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11916     {
11917       if (unformat (i, "node %s", &name))
11918         ;
11919       else if (unformat (i, "next %s", &next))
11920         ;
11921       else
11922         break;
11923     }
11924   if (name == 0)
11925     {
11926       errmsg ("node name required");
11927       return -99;
11928     }
11929   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11930     {
11931       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11932       return -99;
11933     }
11934   if (next == 0)
11935     {
11936       errmsg ("next node required");
11937       return -99;
11938     }
11939   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11940     {
11941       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11942       return -99;
11943     }
11944
11945   M (ADD_NODE_NEXT, mp);
11946   clib_memcpy (mp->node_name, name, vec_len (name));
11947   clib_memcpy (mp->next_name, next, vec_len (next));
11948   vec_free (name);
11949   vec_free (next);
11950
11951   S (mp);
11952   W (ret);
11953   return ret;
11954 }
11955
11956 static int
11957 api_l2tpv3_create_tunnel (vat_main_t * vam)
11958 {
11959   unformat_input_t *i = vam->input;
11960   ip6_address_t client_address, our_address;
11961   int client_address_set = 0;
11962   int our_address_set = 0;
11963   u32 local_session_id = 0;
11964   u32 remote_session_id = 0;
11965   u64 local_cookie = 0;
11966   u64 remote_cookie = 0;
11967   u8 l2_sublayer_present = 0;
11968   vl_api_l2tpv3_create_tunnel_t *mp;
11969   int ret;
11970
11971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11972     {
11973       if (unformat (i, "client_address %U", unformat_ip6_address,
11974                     &client_address))
11975         client_address_set = 1;
11976       else if (unformat (i, "our_address %U", unformat_ip6_address,
11977                          &our_address))
11978         our_address_set = 1;
11979       else if (unformat (i, "local_session_id %d", &local_session_id))
11980         ;
11981       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11982         ;
11983       else if (unformat (i, "local_cookie %lld", &local_cookie))
11984         ;
11985       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11986         ;
11987       else if (unformat (i, "l2-sublayer-present"))
11988         l2_sublayer_present = 1;
11989       else
11990         break;
11991     }
11992
11993   if (client_address_set == 0)
11994     {
11995       errmsg ("client_address required");
11996       return -99;
11997     }
11998
11999   if (our_address_set == 0)
12000     {
12001       errmsg ("our_address required");
12002       return -99;
12003     }
12004
12005   M (L2TPV3_CREATE_TUNNEL, mp);
12006
12007   clib_memcpy (mp->client_address, client_address.as_u8,
12008                sizeof (mp->client_address));
12009
12010   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12011
12012   mp->local_session_id = ntohl (local_session_id);
12013   mp->remote_session_id = ntohl (remote_session_id);
12014   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12015   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12016   mp->l2_sublayer_present = l2_sublayer_present;
12017   mp->is_ipv6 = 1;
12018
12019   S (mp);
12020   W (ret);
12021   return ret;
12022 }
12023
12024 static int
12025 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12026 {
12027   unformat_input_t *i = vam->input;
12028   u32 sw_if_index;
12029   u8 sw_if_index_set = 0;
12030   u64 new_local_cookie = 0;
12031   u64 new_remote_cookie = 0;
12032   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12033   int ret;
12034
12035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12036     {
12037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12040         sw_if_index_set = 1;
12041       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12042         ;
12043       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12044         ;
12045       else
12046         break;
12047     }
12048
12049   if (sw_if_index_set == 0)
12050     {
12051       errmsg ("missing interface name or sw_if_index");
12052       return -99;
12053     }
12054
12055   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12056
12057   mp->sw_if_index = ntohl (sw_if_index);
12058   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12059   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12060
12061   S (mp);
12062   W (ret);
12063   return ret;
12064 }
12065
12066 static int
12067 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12068 {
12069   unformat_input_t *i = vam->input;
12070   vl_api_l2tpv3_interface_enable_disable_t *mp;
12071   u32 sw_if_index;
12072   u8 sw_if_index_set = 0;
12073   u8 enable_disable = 1;
12074   int ret;
12075
12076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12077     {
12078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12079         sw_if_index_set = 1;
12080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12081         sw_if_index_set = 1;
12082       else if (unformat (i, "enable"))
12083         enable_disable = 1;
12084       else if (unformat (i, "disable"))
12085         enable_disable = 0;
12086       else
12087         break;
12088     }
12089
12090   if (sw_if_index_set == 0)
12091     {
12092       errmsg ("missing interface name or sw_if_index");
12093       return -99;
12094     }
12095
12096   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12097
12098   mp->sw_if_index = ntohl (sw_if_index);
12099   mp->enable_disable = enable_disable;
12100
12101   S (mp);
12102   W (ret);
12103   return ret;
12104 }
12105
12106 static int
12107 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12108 {
12109   unformat_input_t *i = vam->input;
12110   vl_api_l2tpv3_set_lookup_key_t *mp;
12111   u8 key = ~0;
12112   int ret;
12113
12114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12115     {
12116       if (unformat (i, "lookup_v6_src"))
12117         key = L2T_LOOKUP_SRC_ADDRESS;
12118       else if (unformat (i, "lookup_v6_dst"))
12119         key = L2T_LOOKUP_DST_ADDRESS;
12120       else if (unformat (i, "lookup_session_id"))
12121         key = L2T_LOOKUP_SESSION_ID;
12122       else
12123         break;
12124     }
12125
12126   if (key == (u8) ~ 0)
12127     {
12128       errmsg ("l2tp session lookup key unset");
12129       return -99;
12130     }
12131
12132   M (L2TPV3_SET_LOOKUP_KEY, mp);
12133
12134   mp->key = key;
12135
12136   S (mp);
12137   W (ret);
12138   return ret;
12139 }
12140
12141 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12142   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12143 {
12144   vat_main_t *vam = &vat_main;
12145
12146   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12147          format_ip6_address, mp->our_address,
12148          format_ip6_address, mp->client_address,
12149          clib_net_to_host_u32 (mp->sw_if_index));
12150
12151   print (vam->ofp,
12152          "   local cookies %016llx %016llx remote cookie %016llx",
12153          clib_net_to_host_u64 (mp->local_cookie[0]),
12154          clib_net_to_host_u64 (mp->local_cookie[1]),
12155          clib_net_to_host_u64 (mp->remote_cookie));
12156
12157   print (vam->ofp, "   local session-id %d remote session-id %d",
12158          clib_net_to_host_u32 (mp->local_session_id),
12159          clib_net_to_host_u32 (mp->remote_session_id));
12160
12161   print (vam->ofp, "   l2 specific sublayer %s\n",
12162          mp->l2_sublayer_present ? "preset" : "absent");
12163
12164 }
12165
12166 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12167   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12168 {
12169   vat_main_t *vam = &vat_main;
12170   vat_json_node_t *node = NULL;
12171   struct in6_addr addr;
12172
12173   if (VAT_JSON_ARRAY != vam->json_tree.type)
12174     {
12175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12176       vat_json_init_array (&vam->json_tree);
12177     }
12178   node = vat_json_array_add (&vam->json_tree);
12179
12180   vat_json_init_object (node);
12181
12182   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12183   vat_json_object_add_ip6 (node, "our_address", addr);
12184   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12185   vat_json_object_add_ip6 (node, "client_address", addr);
12186
12187   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12188   vat_json_init_array (lc);
12189   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12190   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12191   vat_json_object_add_uint (node, "remote_cookie",
12192                             clib_net_to_host_u64 (mp->remote_cookie));
12193
12194   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12195   vat_json_object_add_uint (node, "local_session_id",
12196                             clib_net_to_host_u32 (mp->local_session_id));
12197   vat_json_object_add_uint (node, "remote_session_id",
12198                             clib_net_to_host_u32 (mp->remote_session_id));
12199   vat_json_object_add_string_copy (node, "l2_sublayer",
12200                                    mp->l2_sublayer_present ? (u8 *) "present"
12201                                    : (u8 *) "absent");
12202 }
12203
12204 static int
12205 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12206 {
12207   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12208   vl_api_control_ping_t *mp_ping;
12209   int ret;
12210
12211   /* Get list of l2tpv3-tunnel interfaces */
12212   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12213   S (mp);
12214
12215   /* Use a control ping for synchronization */
12216   MPING (CONTROL_PING, mp_ping);
12217   S (mp_ping);
12218
12219   W (ret);
12220   return ret;
12221 }
12222
12223
12224 static void vl_api_sw_interface_tap_v2_details_t_handler
12225   (vl_api_sw_interface_tap_v2_details_t * mp)
12226 {
12227   vat_main_t *vam = &vat_main;
12228
12229   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12230                     mp->host_ip4_prefix_len);
12231   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12232                     mp->host_ip6_prefix_len);
12233
12234   print (vam->ofp,
12235          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12236          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12237          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12238          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12239          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12240
12241   vec_free (ip4);
12242   vec_free (ip6);
12243 }
12244
12245 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12246   (vl_api_sw_interface_tap_v2_details_t * mp)
12247 {
12248   vat_main_t *vam = &vat_main;
12249   vat_json_node_t *node = NULL;
12250
12251   if (VAT_JSON_ARRAY != vam->json_tree.type)
12252     {
12253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12254       vat_json_init_array (&vam->json_tree);
12255     }
12256   node = vat_json_array_add (&vam->json_tree);
12257
12258   vat_json_init_object (node);
12259   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12261   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12262   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12263   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12264   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12265   vat_json_object_add_string_copy (node, "host_mac_addr",
12266                                    format (0, "%U", format_ethernet_address,
12267                                            &mp->host_mac_addr));
12268   vat_json_object_add_string_copy (node, "host_namespace",
12269                                    mp->host_namespace);
12270   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12271   vat_json_object_add_string_copy (node, "host_ip4_addr",
12272                                    format (0, "%U/%d", format_ip4_address,
12273                                            mp->host_ip4_addr,
12274                                            mp->host_ip4_prefix_len));
12275   vat_json_object_add_string_copy (node, "host_ip6_addr",
12276                                    format (0, "%U/%d", format_ip6_address,
12277                                            mp->host_ip6_addr,
12278                                            mp->host_ip6_prefix_len));
12279
12280 }
12281
12282 static int
12283 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12284 {
12285   vl_api_sw_interface_tap_v2_dump_t *mp;
12286   vl_api_control_ping_t *mp_ping;
12287   int ret;
12288
12289   print (vam->ofp,
12290          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12291          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12292          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12293          "host_ip6_addr");
12294
12295   /* Get list of tap interfaces */
12296   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12297   S (mp);
12298
12299   /* Use a control ping for synchronization */
12300   MPING (CONTROL_PING, mp_ping);
12301   S (mp_ping);
12302
12303   W (ret);
12304   return ret;
12305 }
12306
12307 static void vl_api_sw_interface_virtio_pci_details_t_handler
12308   (vl_api_sw_interface_virtio_pci_details_t * mp)
12309 {
12310   vat_main_t *vam = &vat_main;
12311
12312   typedef union
12313   {
12314     struct
12315     {
12316       u16 domain;
12317       u8 bus;
12318       u8 slot:5;
12319       u8 function:3;
12320     };
12321     u32 as_u32;
12322   } pci_addr_t;
12323   pci_addr_t addr;
12324   addr.as_u32 = ntohl (mp->pci_addr);
12325   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12326                          addr.slot, addr.function);
12327
12328   print (vam->ofp,
12329          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12330          pci_addr, ntohl (mp->sw_if_index),
12331          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12332          format_ethernet_address, mp->mac_addr,
12333          clib_net_to_host_u64 (mp->features));
12334   vec_free (pci_addr);
12335 }
12336
12337 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12338   (vl_api_sw_interface_virtio_pci_details_t * mp)
12339 {
12340   vat_main_t *vam = &vat_main;
12341   vat_json_node_t *node = NULL;
12342
12343   if (VAT_JSON_ARRAY != vam->json_tree.type)
12344     {
12345       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12346       vat_json_init_array (&vam->json_tree);
12347     }
12348   node = vat_json_array_add (&vam->json_tree);
12349
12350   vat_json_init_object (node);
12351   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12352   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12353   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12354   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12355   vat_json_object_add_uint (node, "features",
12356                             clib_net_to_host_u64 (mp->features));
12357   vat_json_object_add_string_copy (node, "mac_addr",
12358                                    format (0, "%U", format_ethernet_address,
12359                                            &mp->mac_addr));
12360 }
12361
12362 static int
12363 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12364 {
12365   vl_api_sw_interface_virtio_pci_dump_t *mp;
12366   vl_api_control_ping_t *mp_ping;
12367   int ret;
12368
12369   print (vam->ofp,
12370          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12371          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12372          "mac_addr", "features");
12373
12374   /* Get list of tap interfaces */
12375   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12376   S (mp);
12377
12378   /* Use a control ping for synchronization */
12379   MPING (CONTROL_PING, mp_ping);
12380   S (mp_ping);
12381
12382   W (ret);
12383   return ret;
12384 }
12385
12386 static int
12387 api_vxlan_offload_rx (vat_main_t * vam)
12388 {
12389   unformat_input_t *line_input = vam->input;
12390   vl_api_vxlan_offload_rx_t *mp;
12391   u32 hw_if_index = ~0, rx_if_index = ~0;
12392   u8 is_add = 1;
12393   int ret;
12394
12395   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12396     {
12397       if (unformat (line_input, "del"))
12398         is_add = 0;
12399       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12400                          &hw_if_index))
12401         ;
12402       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12403         ;
12404       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12405                          &rx_if_index))
12406         ;
12407       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12408         ;
12409       else
12410         {
12411           errmsg ("parse error '%U'", format_unformat_error, line_input);
12412           return -99;
12413         }
12414     }
12415
12416   if (hw_if_index == ~0)
12417     {
12418       errmsg ("no hw interface");
12419       return -99;
12420     }
12421
12422   if (rx_if_index == ~0)
12423     {
12424       errmsg ("no rx tunnel");
12425       return -99;
12426     }
12427
12428   M (VXLAN_OFFLOAD_RX, mp);
12429
12430   mp->hw_if_index = ntohl (hw_if_index);
12431   mp->sw_if_index = ntohl (rx_if_index);
12432   mp->enable = is_add;
12433
12434   S (mp);
12435   W (ret);
12436   return ret;
12437 }
12438
12439 static uword unformat_vxlan_decap_next
12440   (unformat_input_t * input, va_list * args)
12441 {
12442   u32 *result = va_arg (*args, u32 *);
12443   u32 tmp;
12444
12445   if (unformat (input, "l2"))
12446     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12447   else if (unformat (input, "%d", &tmp))
12448     *result = tmp;
12449   else
12450     return 0;
12451   return 1;
12452 }
12453
12454 static int
12455 api_vxlan_add_del_tunnel (vat_main_t * vam)
12456 {
12457   unformat_input_t *line_input = vam->input;
12458   vl_api_vxlan_add_del_tunnel_t *mp;
12459   ip46_address_t src, dst;
12460   u8 is_add = 1;
12461   u8 ipv4_set = 0, ipv6_set = 0;
12462   u8 src_set = 0;
12463   u8 dst_set = 0;
12464   u8 grp_set = 0;
12465   u32 instance = ~0;
12466   u32 mcast_sw_if_index = ~0;
12467   u32 encap_vrf_id = 0;
12468   u32 decap_next_index = ~0;
12469   u32 vni = 0;
12470   int ret;
12471
12472   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12473   clib_memset (&src, 0, sizeof src);
12474   clib_memset (&dst, 0, sizeof dst);
12475
12476   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12477     {
12478       if (unformat (line_input, "del"))
12479         is_add = 0;
12480       else if (unformat (line_input, "instance %d", &instance))
12481         ;
12482       else
12483         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12484         {
12485           ipv4_set = 1;
12486           src_set = 1;
12487         }
12488       else
12489         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12490         {
12491           ipv4_set = 1;
12492           dst_set = 1;
12493         }
12494       else
12495         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12496         {
12497           ipv6_set = 1;
12498           src_set = 1;
12499         }
12500       else
12501         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12502         {
12503           ipv6_set = 1;
12504           dst_set = 1;
12505         }
12506       else if (unformat (line_input, "group %U %U",
12507                          unformat_ip4_address, &dst.ip4,
12508                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12509         {
12510           grp_set = dst_set = 1;
12511           ipv4_set = 1;
12512         }
12513       else if (unformat (line_input, "group %U",
12514                          unformat_ip4_address, &dst.ip4))
12515         {
12516           grp_set = dst_set = 1;
12517           ipv4_set = 1;
12518         }
12519       else if (unformat (line_input, "group %U %U",
12520                          unformat_ip6_address, &dst.ip6,
12521                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12522         {
12523           grp_set = dst_set = 1;
12524           ipv6_set = 1;
12525         }
12526       else if (unformat (line_input, "group %U",
12527                          unformat_ip6_address, &dst.ip6))
12528         {
12529           grp_set = dst_set = 1;
12530           ipv6_set = 1;
12531         }
12532       else
12533         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12534         ;
12535       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12536         ;
12537       else if (unformat (line_input, "decap-next %U",
12538                          unformat_vxlan_decap_next, &decap_next_index))
12539         ;
12540       else if (unformat (line_input, "vni %d", &vni))
12541         ;
12542       else
12543         {
12544           errmsg ("parse error '%U'", format_unformat_error, line_input);
12545           return -99;
12546         }
12547     }
12548
12549   if (src_set == 0)
12550     {
12551       errmsg ("tunnel src address not specified");
12552       return -99;
12553     }
12554   if (dst_set == 0)
12555     {
12556       errmsg ("tunnel dst address not specified");
12557       return -99;
12558     }
12559
12560   if (grp_set && !ip46_address_is_multicast (&dst))
12561     {
12562       errmsg ("tunnel group address not multicast");
12563       return -99;
12564     }
12565   if (grp_set && mcast_sw_if_index == ~0)
12566     {
12567       errmsg ("tunnel nonexistent multicast device");
12568       return -99;
12569     }
12570   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12571     {
12572       errmsg ("tunnel dst address must be unicast");
12573       return -99;
12574     }
12575
12576
12577   if (ipv4_set && ipv6_set)
12578     {
12579       errmsg ("both IPv4 and IPv6 addresses specified");
12580       return -99;
12581     }
12582
12583   if ((vni == 0) || (vni >> 24))
12584     {
12585       errmsg ("vni not specified or out of range");
12586       return -99;
12587     }
12588
12589   M (VXLAN_ADD_DEL_TUNNEL, mp);
12590
12591   if (ipv6_set)
12592     {
12593       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12594       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12595     }
12596   else
12597     {
12598       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12599       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12600     }
12601
12602   mp->instance = htonl (instance);
12603   mp->encap_vrf_id = ntohl (encap_vrf_id);
12604   mp->decap_next_index = ntohl (decap_next_index);
12605   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12606   mp->vni = ntohl (vni);
12607   mp->is_add = is_add;
12608   mp->is_ipv6 = ipv6_set;
12609
12610   S (mp);
12611   W (ret);
12612   return ret;
12613 }
12614
12615 static void vl_api_vxlan_tunnel_details_t_handler
12616   (vl_api_vxlan_tunnel_details_t * mp)
12617 {
12618   vat_main_t *vam = &vat_main;
12619   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12620   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12621
12622   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12623          ntohl (mp->sw_if_index),
12624          ntohl (mp->instance),
12625          format_ip46_address, &src, IP46_TYPE_ANY,
12626          format_ip46_address, &dst, IP46_TYPE_ANY,
12627          ntohl (mp->encap_vrf_id),
12628          ntohl (mp->decap_next_index), ntohl (mp->vni),
12629          ntohl (mp->mcast_sw_if_index));
12630 }
12631
12632 static void vl_api_vxlan_tunnel_details_t_handler_json
12633   (vl_api_vxlan_tunnel_details_t * mp)
12634 {
12635   vat_main_t *vam = &vat_main;
12636   vat_json_node_t *node = NULL;
12637
12638   if (VAT_JSON_ARRAY != vam->json_tree.type)
12639     {
12640       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12641       vat_json_init_array (&vam->json_tree);
12642     }
12643   node = vat_json_array_add (&vam->json_tree);
12644
12645   vat_json_init_object (node);
12646   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12647
12648   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12649
12650   if (mp->is_ipv6)
12651     {
12652       struct in6_addr ip6;
12653
12654       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12655       vat_json_object_add_ip6 (node, "src_address", ip6);
12656       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12657       vat_json_object_add_ip6 (node, "dst_address", ip6);
12658     }
12659   else
12660     {
12661       struct in_addr ip4;
12662
12663       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12664       vat_json_object_add_ip4 (node, "src_address", ip4);
12665       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12666       vat_json_object_add_ip4 (node, "dst_address", ip4);
12667     }
12668   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12669   vat_json_object_add_uint (node, "decap_next_index",
12670                             ntohl (mp->decap_next_index));
12671   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12672   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12673   vat_json_object_add_uint (node, "mcast_sw_if_index",
12674                             ntohl (mp->mcast_sw_if_index));
12675 }
12676
12677 static int
12678 api_vxlan_tunnel_dump (vat_main_t * vam)
12679 {
12680   unformat_input_t *i = vam->input;
12681   vl_api_vxlan_tunnel_dump_t *mp;
12682   vl_api_control_ping_t *mp_ping;
12683   u32 sw_if_index;
12684   u8 sw_if_index_set = 0;
12685   int ret;
12686
12687   /* Parse args required to build the message */
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "sw_if_index %d", &sw_if_index))
12691         sw_if_index_set = 1;
12692       else
12693         break;
12694     }
12695
12696   if (sw_if_index_set == 0)
12697     {
12698       sw_if_index = ~0;
12699     }
12700
12701   if (!vam->json_output)
12702     {
12703       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12704              "sw_if_index", "instance", "src_address", "dst_address",
12705              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12706     }
12707
12708   /* Get list of vxlan-tunnel interfaces */
12709   M (VXLAN_TUNNEL_DUMP, mp);
12710
12711   mp->sw_if_index = htonl (sw_if_index);
12712
12713   S (mp);
12714
12715   /* Use a control ping for synchronization */
12716   MPING (CONTROL_PING, mp_ping);
12717   S (mp_ping);
12718
12719   W (ret);
12720   return ret;
12721 }
12722
12723 static uword unformat_geneve_decap_next
12724   (unformat_input_t * input, va_list * args)
12725 {
12726   u32 *result = va_arg (*args, u32 *);
12727   u32 tmp;
12728
12729   if (unformat (input, "l2"))
12730     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12731   else if (unformat (input, "%d", &tmp))
12732     *result = tmp;
12733   else
12734     return 0;
12735   return 1;
12736 }
12737
12738 static int
12739 api_geneve_add_del_tunnel (vat_main_t * vam)
12740 {
12741   unformat_input_t *line_input = vam->input;
12742   vl_api_geneve_add_del_tunnel_t *mp;
12743   ip46_address_t src, dst;
12744   u8 is_add = 1;
12745   u8 ipv4_set = 0, ipv6_set = 0;
12746   u8 src_set = 0;
12747   u8 dst_set = 0;
12748   u8 grp_set = 0;
12749   u32 mcast_sw_if_index = ~0;
12750   u32 encap_vrf_id = 0;
12751   u32 decap_next_index = ~0;
12752   u32 vni = 0;
12753   int ret;
12754
12755   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12756   clib_memset (&src, 0, sizeof src);
12757   clib_memset (&dst, 0, sizeof dst);
12758
12759   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (line_input, "del"))
12762         is_add = 0;
12763       else
12764         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12765         {
12766           ipv4_set = 1;
12767           src_set = 1;
12768         }
12769       else
12770         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12771         {
12772           ipv4_set = 1;
12773           dst_set = 1;
12774         }
12775       else
12776         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12777         {
12778           ipv6_set = 1;
12779           src_set = 1;
12780         }
12781       else
12782         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12783         {
12784           ipv6_set = 1;
12785           dst_set = 1;
12786         }
12787       else if (unformat (line_input, "group %U %U",
12788                          unformat_ip4_address, &dst.ip4,
12789                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12790         {
12791           grp_set = dst_set = 1;
12792           ipv4_set = 1;
12793         }
12794       else if (unformat (line_input, "group %U",
12795                          unformat_ip4_address, &dst.ip4))
12796         {
12797           grp_set = dst_set = 1;
12798           ipv4_set = 1;
12799         }
12800       else if (unformat (line_input, "group %U %U",
12801                          unformat_ip6_address, &dst.ip6,
12802                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12803         {
12804           grp_set = dst_set = 1;
12805           ipv6_set = 1;
12806         }
12807       else if (unformat (line_input, "group %U",
12808                          unformat_ip6_address, &dst.ip6))
12809         {
12810           grp_set = dst_set = 1;
12811           ipv6_set = 1;
12812         }
12813       else
12814         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12815         ;
12816       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12817         ;
12818       else if (unformat (line_input, "decap-next %U",
12819                          unformat_geneve_decap_next, &decap_next_index))
12820         ;
12821       else if (unformat (line_input, "vni %d", &vni))
12822         ;
12823       else
12824         {
12825           errmsg ("parse error '%U'", format_unformat_error, line_input);
12826           return -99;
12827         }
12828     }
12829
12830   if (src_set == 0)
12831     {
12832       errmsg ("tunnel src address not specified");
12833       return -99;
12834     }
12835   if (dst_set == 0)
12836     {
12837       errmsg ("tunnel dst address not specified");
12838       return -99;
12839     }
12840
12841   if (grp_set && !ip46_address_is_multicast (&dst))
12842     {
12843       errmsg ("tunnel group address not multicast");
12844       return -99;
12845     }
12846   if (grp_set && mcast_sw_if_index == ~0)
12847     {
12848       errmsg ("tunnel nonexistent multicast device");
12849       return -99;
12850     }
12851   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12852     {
12853       errmsg ("tunnel dst address must be unicast");
12854       return -99;
12855     }
12856
12857
12858   if (ipv4_set && ipv6_set)
12859     {
12860       errmsg ("both IPv4 and IPv6 addresses specified");
12861       return -99;
12862     }
12863
12864   if ((vni == 0) || (vni >> 24))
12865     {
12866       errmsg ("vni not specified or out of range");
12867       return -99;
12868     }
12869
12870   M (GENEVE_ADD_DEL_TUNNEL, mp);
12871
12872   if (ipv6_set)
12873     {
12874       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12875       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12876     }
12877   else
12878     {
12879       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12880       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12881     }
12882   mp->encap_vrf_id = ntohl (encap_vrf_id);
12883   mp->decap_next_index = ntohl (decap_next_index);
12884   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12885   mp->vni = ntohl (vni);
12886   mp->is_add = is_add;
12887   mp->is_ipv6 = ipv6_set;
12888
12889   S (mp);
12890   W (ret);
12891   return ret;
12892 }
12893
12894 static void vl_api_geneve_tunnel_details_t_handler
12895   (vl_api_geneve_tunnel_details_t * mp)
12896 {
12897   vat_main_t *vam = &vat_main;
12898   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12899   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12900
12901   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12902          ntohl (mp->sw_if_index),
12903          format_ip46_address, &src, IP46_TYPE_ANY,
12904          format_ip46_address, &dst, IP46_TYPE_ANY,
12905          ntohl (mp->encap_vrf_id),
12906          ntohl (mp->decap_next_index), ntohl (mp->vni),
12907          ntohl (mp->mcast_sw_if_index));
12908 }
12909
12910 static void vl_api_geneve_tunnel_details_t_handler_json
12911   (vl_api_geneve_tunnel_details_t * mp)
12912 {
12913   vat_main_t *vam = &vat_main;
12914   vat_json_node_t *node = NULL;
12915
12916   if (VAT_JSON_ARRAY != vam->json_tree.type)
12917     {
12918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12919       vat_json_init_array (&vam->json_tree);
12920     }
12921   node = vat_json_array_add (&vam->json_tree);
12922
12923   vat_json_init_object (node);
12924   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12925   if (mp->is_ipv6)
12926     {
12927       struct in6_addr ip6;
12928
12929       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12930       vat_json_object_add_ip6 (node, "src_address", ip6);
12931       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12932       vat_json_object_add_ip6 (node, "dst_address", ip6);
12933     }
12934   else
12935     {
12936       struct in_addr ip4;
12937
12938       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12939       vat_json_object_add_ip4 (node, "src_address", ip4);
12940       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12941       vat_json_object_add_ip4 (node, "dst_address", ip4);
12942     }
12943   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12944   vat_json_object_add_uint (node, "decap_next_index",
12945                             ntohl (mp->decap_next_index));
12946   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12947   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12948   vat_json_object_add_uint (node, "mcast_sw_if_index",
12949                             ntohl (mp->mcast_sw_if_index));
12950 }
12951
12952 static int
12953 api_geneve_tunnel_dump (vat_main_t * vam)
12954 {
12955   unformat_input_t *i = vam->input;
12956   vl_api_geneve_tunnel_dump_t *mp;
12957   vl_api_control_ping_t *mp_ping;
12958   u32 sw_if_index;
12959   u8 sw_if_index_set = 0;
12960   int ret;
12961
12962   /* Parse args required to build the message */
12963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12964     {
12965       if (unformat (i, "sw_if_index %d", &sw_if_index))
12966         sw_if_index_set = 1;
12967       else
12968         break;
12969     }
12970
12971   if (sw_if_index_set == 0)
12972     {
12973       sw_if_index = ~0;
12974     }
12975
12976   if (!vam->json_output)
12977     {
12978       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12979              "sw_if_index", "local_address", "remote_address",
12980              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12981     }
12982
12983   /* Get list of geneve-tunnel interfaces */
12984   M (GENEVE_TUNNEL_DUMP, mp);
12985
12986   mp->sw_if_index = htonl (sw_if_index);
12987
12988   S (mp);
12989
12990   /* Use a control ping for synchronization */
12991   M (CONTROL_PING, mp_ping);
12992   S (mp_ping);
12993
12994   W (ret);
12995   return ret;
12996 }
12997
12998 static int
12999 api_gre_tunnel_add_del (vat_main_t * vam)
13000 {
13001   unformat_input_t *line_input = vam->input;
13002   vl_api_address_t src = { }, dst =
13003   {
13004   };
13005   vl_api_gre_tunnel_add_del_t *mp;
13006   vl_api_gre_tunnel_type_t t_type;
13007   u8 is_add = 1;
13008   u8 src_set = 0;
13009   u8 dst_set = 0;
13010   u32 outer_fib_id = 0;
13011   u32 session_id = 0;
13012   u32 instance = ~0;
13013   int ret;
13014
13015   t_type = GRE_API_TUNNEL_TYPE_L3;
13016
13017   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13018     {
13019       if (unformat (line_input, "del"))
13020         is_add = 0;
13021       else if (unformat (line_input, "instance %d", &instance))
13022         ;
13023       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13024         {
13025           src_set = 1;
13026         }
13027       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13028         {
13029           dst_set = 1;
13030         }
13031       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13032         ;
13033       else if (unformat (line_input, "teb"))
13034         t_type = GRE_API_TUNNEL_TYPE_TEB;
13035       else if (unformat (line_input, "erspan %d", &session_id))
13036         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13037       else
13038         {
13039           errmsg ("parse error '%U'", format_unformat_error, line_input);
13040           return -99;
13041         }
13042     }
13043
13044   if (src_set == 0)
13045     {
13046       errmsg ("tunnel src address not specified");
13047       return -99;
13048     }
13049   if (dst_set == 0)
13050     {
13051       errmsg ("tunnel dst address not specified");
13052       return -99;
13053     }
13054
13055   M (GRE_TUNNEL_ADD_DEL, mp);
13056
13057   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13058   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13059
13060   mp->tunnel.instance = htonl (instance);
13061   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13062   mp->is_add = is_add;
13063   mp->tunnel.session_id = htons ((u16) session_id);
13064   mp->tunnel.type = htonl (t_type);
13065
13066   S (mp);
13067   W (ret);
13068   return ret;
13069 }
13070
13071 static void vl_api_gre_tunnel_details_t_handler
13072   (vl_api_gre_tunnel_details_t * mp)
13073 {
13074   vat_main_t *vam = &vat_main;
13075
13076   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13077          ntohl (mp->tunnel.sw_if_index),
13078          ntohl (mp->tunnel.instance),
13079          format_vl_api_address, &mp->tunnel.src,
13080          format_vl_api_address, &mp->tunnel.dst,
13081          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13082          ntohl (mp->tunnel.session_id));
13083 }
13084
13085 static void vl_api_gre_tunnel_details_t_handler_json
13086   (vl_api_gre_tunnel_details_t * mp)
13087 {
13088   vat_main_t *vam = &vat_main;
13089   vat_json_node_t *node = NULL;
13090
13091   if (VAT_JSON_ARRAY != vam->json_tree.type)
13092     {
13093       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13094       vat_json_init_array (&vam->json_tree);
13095     }
13096   node = vat_json_array_add (&vam->json_tree);
13097
13098   vat_json_init_object (node);
13099   vat_json_object_add_uint (node, "sw_if_index",
13100                             ntohl (mp->tunnel.sw_if_index));
13101   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13102
13103   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13104   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13105   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13106   vat_json_object_add_uint (node, "outer_fib_id",
13107                             ntohl (mp->tunnel.outer_fib_id));
13108   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13109 }
13110
13111 static int
13112 api_gre_tunnel_dump (vat_main_t * vam)
13113 {
13114   unformat_input_t *i = vam->input;
13115   vl_api_gre_tunnel_dump_t *mp;
13116   vl_api_control_ping_t *mp_ping;
13117   u32 sw_if_index;
13118   u8 sw_if_index_set = 0;
13119   int ret;
13120
13121   /* Parse args required to build the message */
13122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13123     {
13124       if (unformat (i, "sw_if_index %d", &sw_if_index))
13125         sw_if_index_set = 1;
13126       else
13127         break;
13128     }
13129
13130   if (sw_if_index_set == 0)
13131     {
13132       sw_if_index = ~0;
13133     }
13134
13135   if (!vam->json_output)
13136     {
13137       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13138              "sw_if_index", "instance", "src_address", "dst_address",
13139              "tunnel_type", "outer_fib_id", "session_id");
13140     }
13141
13142   /* Get list of gre-tunnel interfaces */
13143   M (GRE_TUNNEL_DUMP, mp);
13144
13145   mp->sw_if_index = htonl (sw_if_index);
13146
13147   S (mp);
13148
13149   /* Use a control ping for synchronization */
13150   MPING (CONTROL_PING, mp_ping);
13151   S (mp_ping);
13152
13153   W (ret);
13154   return ret;
13155 }
13156
13157 static int
13158 api_l2_fib_clear_table (vat_main_t * vam)
13159 {
13160 //  unformat_input_t * i = vam->input;
13161   vl_api_l2_fib_clear_table_t *mp;
13162   int ret;
13163
13164   M (L2_FIB_CLEAR_TABLE, mp);
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static int
13172 api_l2_interface_efp_filter (vat_main_t * vam)
13173 {
13174   unformat_input_t *i = vam->input;
13175   vl_api_l2_interface_efp_filter_t *mp;
13176   u32 sw_if_index;
13177   u8 enable = 1;
13178   u8 sw_if_index_set = 0;
13179   int ret;
13180
13181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13182     {
13183       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13184         sw_if_index_set = 1;
13185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13186         sw_if_index_set = 1;
13187       else if (unformat (i, "enable"))
13188         enable = 1;
13189       else if (unformat (i, "disable"))
13190         enable = 0;
13191       else
13192         {
13193           clib_warning ("parse error '%U'", format_unformat_error, i);
13194           return -99;
13195         }
13196     }
13197
13198   if (sw_if_index_set == 0)
13199     {
13200       errmsg ("missing sw_if_index");
13201       return -99;
13202     }
13203
13204   M (L2_INTERFACE_EFP_FILTER, mp);
13205
13206   mp->sw_if_index = ntohl (sw_if_index);
13207   mp->enable_disable = enable;
13208
13209   S (mp);
13210   W (ret);
13211   return ret;
13212 }
13213
13214 #define foreach_vtr_op                          \
13215 _("disable",  L2_VTR_DISABLED)                  \
13216 _("push-1",  L2_VTR_PUSH_1)                     \
13217 _("push-2",  L2_VTR_PUSH_2)                     \
13218 _("pop-1",  L2_VTR_POP_1)                       \
13219 _("pop-2",  L2_VTR_POP_2)                       \
13220 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13221 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13222 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13223 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13224
13225 static int
13226 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13227 {
13228   unformat_input_t *i = vam->input;
13229   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13230   u32 sw_if_index;
13231   u8 sw_if_index_set = 0;
13232   u8 vtr_op_set = 0;
13233   u32 vtr_op = 0;
13234   u32 push_dot1q = 1;
13235   u32 tag1 = ~0;
13236   u32 tag2 = ~0;
13237   int ret;
13238
13239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13240     {
13241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13242         sw_if_index_set = 1;
13243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13244         sw_if_index_set = 1;
13245       else if (unformat (i, "vtr_op %d", &vtr_op))
13246         vtr_op_set = 1;
13247 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13248       foreach_vtr_op
13249 #undef _
13250         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13251         ;
13252       else if (unformat (i, "tag1 %d", &tag1))
13253         ;
13254       else if (unformat (i, "tag2 %d", &tag2))
13255         ;
13256       else
13257         {
13258           clib_warning ("parse error '%U'", format_unformat_error, i);
13259           return -99;
13260         }
13261     }
13262
13263   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13264     {
13265       errmsg ("missing vtr operation or sw_if_index");
13266       return -99;
13267     }
13268
13269   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13270   mp->sw_if_index = ntohl (sw_if_index);
13271   mp->vtr_op = ntohl (vtr_op);
13272   mp->push_dot1q = ntohl (push_dot1q);
13273   mp->tag1 = ntohl (tag1);
13274   mp->tag2 = ntohl (tag2);
13275
13276   S (mp);
13277   W (ret);
13278   return ret;
13279 }
13280
13281 static int
13282 api_create_vhost_user_if (vat_main_t * vam)
13283 {
13284   unformat_input_t *i = vam->input;
13285   vl_api_create_vhost_user_if_t *mp;
13286   u8 *file_name;
13287   u8 is_server = 0;
13288   u8 file_name_set = 0;
13289   u32 custom_dev_instance = ~0;
13290   u8 hwaddr[6];
13291   u8 use_custom_mac = 0;
13292   u8 disable_mrg_rxbuf = 0;
13293   u8 disable_indirect_desc = 0;
13294   u8 *tag = 0;
13295   int ret;
13296
13297   /* Shut up coverity */
13298   clib_memset (hwaddr, 0, sizeof (hwaddr));
13299
13300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13301     {
13302       if (unformat (i, "socket %s", &file_name))
13303         {
13304           file_name_set = 1;
13305         }
13306       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13307         ;
13308       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13309         use_custom_mac = 1;
13310       else if (unformat (i, "server"))
13311         is_server = 1;
13312       else if (unformat (i, "disable_mrg_rxbuf"))
13313         disable_mrg_rxbuf = 1;
13314       else if (unformat (i, "disable_indirect_desc"))
13315         disable_indirect_desc = 1;
13316       else if (unformat (i, "tag %s", &tag))
13317         ;
13318       else
13319         break;
13320     }
13321
13322   if (file_name_set == 0)
13323     {
13324       errmsg ("missing socket file name");
13325       return -99;
13326     }
13327
13328   if (vec_len (file_name) > 255)
13329     {
13330       errmsg ("socket file name too long");
13331       return -99;
13332     }
13333   vec_add1 (file_name, 0);
13334
13335   M (CREATE_VHOST_USER_IF, mp);
13336
13337   mp->is_server = is_server;
13338   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13339   mp->disable_indirect_desc = disable_indirect_desc;
13340   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13341   vec_free (file_name);
13342   if (custom_dev_instance != ~0)
13343     {
13344       mp->renumber = 1;
13345       mp->custom_dev_instance = ntohl (custom_dev_instance);
13346     }
13347
13348   mp->use_custom_mac = use_custom_mac;
13349   clib_memcpy (mp->mac_address, hwaddr, 6);
13350   if (tag)
13351     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13352   vec_free (tag);
13353
13354   S (mp);
13355   W (ret);
13356   return ret;
13357 }
13358
13359 static int
13360 api_modify_vhost_user_if (vat_main_t * vam)
13361 {
13362   unformat_input_t *i = vam->input;
13363   vl_api_modify_vhost_user_if_t *mp;
13364   u8 *file_name;
13365   u8 is_server = 0;
13366   u8 file_name_set = 0;
13367   u32 custom_dev_instance = ~0;
13368   u8 sw_if_index_set = 0;
13369   u32 sw_if_index = (u32) ~ 0;
13370   int ret;
13371
13372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13373     {
13374       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13375         sw_if_index_set = 1;
13376       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13377         sw_if_index_set = 1;
13378       else if (unformat (i, "socket %s", &file_name))
13379         {
13380           file_name_set = 1;
13381         }
13382       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13383         ;
13384       else if (unformat (i, "server"))
13385         is_server = 1;
13386       else
13387         break;
13388     }
13389
13390   if (sw_if_index_set == 0)
13391     {
13392       errmsg ("missing sw_if_index or interface name");
13393       return -99;
13394     }
13395
13396   if (file_name_set == 0)
13397     {
13398       errmsg ("missing socket file name");
13399       return -99;
13400     }
13401
13402   if (vec_len (file_name) > 255)
13403     {
13404       errmsg ("socket file name too long");
13405       return -99;
13406     }
13407   vec_add1 (file_name, 0);
13408
13409   M (MODIFY_VHOST_USER_IF, mp);
13410
13411   mp->sw_if_index = ntohl (sw_if_index);
13412   mp->is_server = is_server;
13413   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13414   vec_free (file_name);
13415   if (custom_dev_instance != ~0)
13416     {
13417       mp->renumber = 1;
13418       mp->custom_dev_instance = ntohl (custom_dev_instance);
13419     }
13420
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static int
13427 api_delete_vhost_user_if (vat_main_t * vam)
13428 {
13429   unformat_input_t *i = vam->input;
13430   vl_api_delete_vhost_user_if_t *mp;
13431   u32 sw_if_index = ~0;
13432   u8 sw_if_index_set = 0;
13433   int ret;
13434
13435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13436     {
13437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13438         sw_if_index_set = 1;
13439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13440         sw_if_index_set = 1;
13441       else
13442         break;
13443     }
13444
13445   if (sw_if_index_set == 0)
13446     {
13447       errmsg ("missing sw_if_index or interface name");
13448       return -99;
13449     }
13450
13451
13452   M (DELETE_VHOST_USER_IF, mp);
13453
13454   mp->sw_if_index = ntohl (sw_if_index);
13455
13456   S (mp);
13457   W (ret);
13458   return ret;
13459 }
13460
13461 static void vl_api_sw_interface_vhost_user_details_t_handler
13462   (vl_api_sw_interface_vhost_user_details_t * mp)
13463 {
13464   vat_main_t *vam = &vat_main;
13465
13466   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13467          (char *) mp->interface_name,
13468          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13469          clib_net_to_host_u64 (mp->features), mp->is_server,
13470          ntohl (mp->num_regions), (char *) mp->sock_filename);
13471   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13472 }
13473
13474 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13475   (vl_api_sw_interface_vhost_user_details_t * mp)
13476 {
13477   vat_main_t *vam = &vat_main;
13478   vat_json_node_t *node = NULL;
13479
13480   if (VAT_JSON_ARRAY != vam->json_tree.type)
13481     {
13482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13483       vat_json_init_array (&vam->json_tree);
13484     }
13485   node = vat_json_array_add (&vam->json_tree);
13486
13487   vat_json_init_object (node);
13488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13489   vat_json_object_add_string_copy (node, "interface_name",
13490                                    mp->interface_name);
13491   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13492                             ntohl (mp->virtio_net_hdr_sz));
13493   vat_json_object_add_uint (node, "features",
13494                             clib_net_to_host_u64 (mp->features));
13495   vat_json_object_add_uint (node, "is_server", mp->is_server);
13496   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13497   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13498   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13499 }
13500
13501 static int
13502 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13503 {
13504   vl_api_sw_interface_vhost_user_dump_t *mp;
13505   vl_api_control_ping_t *mp_ping;
13506   int ret;
13507   print (vam->ofp,
13508          "Interface name            idx hdr_sz features server regions filename");
13509
13510   /* Get list of vhost-user interfaces */
13511   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13512   S (mp);
13513
13514   /* Use a control ping for synchronization */
13515   MPING (CONTROL_PING, mp_ping);
13516   S (mp_ping);
13517
13518   W (ret);
13519   return ret;
13520 }
13521
13522 static int
13523 api_show_version (vat_main_t * vam)
13524 {
13525   vl_api_show_version_t *mp;
13526   int ret;
13527
13528   M (SHOW_VERSION, mp);
13529
13530   S (mp);
13531   W (ret);
13532   return ret;
13533 }
13534
13535
13536 static int
13537 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13538 {
13539   unformat_input_t *line_input = vam->input;
13540   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13541   ip4_address_t local4, remote4;
13542   ip6_address_t local6, remote6;
13543   u8 is_add = 1;
13544   u8 ipv4_set = 0, ipv6_set = 0;
13545   u8 local_set = 0;
13546   u8 remote_set = 0;
13547   u8 grp_set = 0;
13548   u32 mcast_sw_if_index = ~0;
13549   u32 encap_vrf_id = 0;
13550   u32 decap_vrf_id = 0;
13551   u8 protocol = ~0;
13552   u32 vni;
13553   u8 vni_set = 0;
13554   int ret;
13555
13556   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13557   clib_memset (&local4, 0, sizeof local4);
13558   clib_memset (&remote4, 0, sizeof remote4);
13559   clib_memset (&local6, 0, sizeof local6);
13560   clib_memset (&remote6, 0, sizeof remote6);
13561
13562   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13563     {
13564       if (unformat (line_input, "del"))
13565         is_add = 0;
13566       else if (unformat (line_input, "local %U",
13567                          unformat_ip4_address, &local4))
13568         {
13569           local_set = 1;
13570           ipv4_set = 1;
13571         }
13572       else if (unformat (line_input, "remote %U",
13573                          unformat_ip4_address, &remote4))
13574         {
13575           remote_set = 1;
13576           ipv4_set = 1;
13577         }
13578       else if (unformat (line_input, "local %U",
13579                          unformat_ip6_address, &local6))
13580         {
13581           local_set = 1;
13582           ipv6_set = 1;
13583         }
13584       else if (unformat (line_input, "remote %U",
13585                          unformat_ip6_address, &remote6))
13586         {
13587           remote_set = 1;
13588           ipv6_set = 1;
13589         }
13590       else if (unformat (line_input, "group %U %U",
13591                          unformat_ip4_address, &remote4,
13592                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13593         {
13594           grp_set = remote_set = 1;
13595           ipv4_set = 1;
13596         }
13597       else if (unformat (line_input, "group %U",
13598                          unformat_ip4_address, &remote4))
13599         {
13600           grp_set = remote_set = 1;
13601           ipv4_set = 1;
13602         }
13603       else if (unformat (line_input, "group %U %U",
13604                          unformat_ip6_address, &remote6,
13605                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13606         {
13607           grp_set = remote_set = 1;
13608           ipv6_set = 1;
13609         }
13610       else if (unformat (line_input, "group %U",
13611                          unformat_ip6_address, &remote6))
13612         {
13613           grp_set = remote_set = 1;
13614           ipv6_set = 1;
13615         }
13616       else
13617         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13618         ;
13619       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13620         ;
13621       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13622         ;
13623       else if (unformat (line_input, "vni %d", &vni))
13624         vni_set = 1;
13625       else if (unformat (line_input, "next-ip4"))
13626         protocol = 1;
13627       else if (unformat (line_input, "next-ip6"))
13628         protocol = 2;
13629       else if (unformat (line_input, "next-ethernet"))
13630         protocol = 3;
13631       else if (unformat (line_input, "next-nsh"))
13632         protocol = 4;
13633       else
13634         {
13635           errmsg ("parse error '%U'", format_unformat_error, line_input);
13636           return -99;
13637         }
13638     }
13639
13640   if (local_set == 0)
13641     {
13642       errmsg ("tunnel local address not specified");
13643       return -99;
13644     }
13645   if (remote_set == 0)
13646     {
13647       errmsg ("tunnel remote address not specified");
13648       return -99;
13649     }
13650   if (grp_set && mcast_sw_if_index == ~0)
13651     {
13652       errmsg ("tunnel nonexistent multicast device");
13653       return -99;
13654     }
13655   if (ipv4_set && ipv6_set)
13656     {
13657       errmsg ("both IPv4 and IPv6 addresses specified");
13658       return -99;
13659     }
13660
13661   if (vni_set == 0)
13662     {
13663       errmsg ("vni not specified");
13664       return -99;
13665     }
13666
13667   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13668
13669
13670   if (ipv6_set)
13671     {
13672       clib_memcpy (&mp->local, &local6, sizeof (local6));
13673       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13674     }
13675   else
13676     {
13677       clib_memcpy (&mp->local, &local4, sizeof (local4));
13678       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13679     }
13680
13681   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13682   mp->encap_vrf_id = ntohl (encap_vrf_id);
13683   mp->decap_vrf_id = ntohl (decap_vrf_id);
13684   mp->protocol = protocol;
13685   mp->vni = ntohl (vni);
13686   mp->is_add = is_add;
13687   mp->is_ipv6 = ipv6_set;
13688
13689   S (mp);
13690   W (ret);
13691   return ret;
13692 }
13693
13694 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13695   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13696 {
13697   vat_main_t *vam = &vat_main;
13698   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13699   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13700
13701   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13702          ntohl (mp->sw_if_index),
13703          format_ip46_address, &local, IP46_TYPE_ANY,
13704          format_ip46_address, &remote, IP46_TYPE_ANY,
13705          ntohl (mp->vni), mp->protocol,
13706          ntohl (mp->mcast_sw_if_index),
13707          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13708 }
13709
13710
13711 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13712   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13713 {
13714   vat_main_t *vam = &vat_main;
13715   vat_json_node_t *node = NULL;
13716   struct in_addr ip4;
13717   struct in6_addr ip6;
13718
13719   if (VAT_JSON_ARRAY != vam->json_tree.type)
13720     {
13721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13722       vat_json_init_array (&vam->json_tree);
13723     }
13724   node = vat_json_array_add (&vam->json_tree);
13725
13726   vat_json_init_object (node);
13727   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13728   if (mp->is_ipv6)
13729     {
13730       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13731       vat_json_object_add_ip6 (node, "local", ip6);
13732       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13733       vat_json_object_add_ip6 (node, "remote", ip6);
13734     }
13735   else
13736     {
13737       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13738       vat_json_object_add_ip4 (node, "local", ip4);
13739       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13740       vat_json_object_add_ip4 (node, "remote", ip4);
13741     }
13742   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13743   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13744   vat_json_object_add_uint (node, "mcast_sw_if_index",
13745                             ntohl (mp->mcast_sw_if_index));
13746   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13747   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13748   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13749 }
13750
13751 static int
13752 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13753 {
13754   unformat_input_t *i = vam->input;
13755   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13756   vl_api_control_ping_t *mp_ping;
13757   u32 sw_if_index;
13758   u8 sw_if_index_set = 0;
13759   int ret;
13760
13761   /* Parse args required to build the message */
13762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13763     {
13764       if (unformat (i, "sw_if_index %d", &sw_if_index))
13765         sw_if_index_set = 1;
13766       else
13767         break;
13768     }
13769
13770   if (sw_if_index_set == 0)
13771     {
13772       sw_if_index = ~0;
13773     }
13774
13775   if (!vam->json_output)
13776     {
13777       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13778              "sw_if_index", "local", "remote", "vni",
13779              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13780     }
13781
13782   /* Get list of vxlan-tunnel interfaces */
13783   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13784
13785   mp->sw_if_index = htonl (sw_if_index);
13786
13787   S (mp);
13788
13789   /* Use a control ping for synchronization */
13790   MPING (CONTROL_PING, mp_ping);
13791   S (mp_ping);
13792
13793   W (ret);
13794   return ret;
13795 }
13796
13797 static void vl_api_l2_fib_table_details_t_handler
13798   (vl_api_l2_fib_table_details_t * mp)
13799 {
13800   vat_main_t *vam = &vat_main;
13801
13802   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13803          "       %d       %d     %d",
13804          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13805          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13806          mp->bvi_mac);
13807 }
13808
13809 static void vl_api_l2_fib_table_details_t_handler_json
13810   (vl_api_l2_fib_table_details_t * mp)
13811 {
13812   vat_main_t *vam = &vat_main;
13813   vat_json_node_t *node = NULL;
13814
13815   if (VAT_JSON_ARRAY != vam->json_tree.type)
13816     {
13817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13818       vat_json_init_array (&vam->json_tree);
13819     }
13820   node = vat_json_array_add (&vam->json_tree);
13821
13822   vat_json_init_object (node);
13823   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13824   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13825   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13826   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13827   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13828   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13829 }
13830
13831 static int
13832 api_l2_fib_table_dump (vat_main_t * vam)
13833 {
13834   unformat_input_t *i = vam->input;
13835   vl_api_l2_fib_table_dump_t *mp;
13836   vl_api_control_ping_t *mp_ping;
13837   u32 bd_id;
13838   u8 bd_id_set = 0;
13839   int ret;
13840
13841   /* Parse args required to build the message */
13842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13843     {
13844       if (unformat (i, "bd_id %d", &bd_id))
13845         bd_id_set = 1;
13846       else
13847         break;
13848     }
13849
13850   if (bd_id_set == 0)
13851     {
13852       errmsg ("missing bridge domain");
13853       return -99;
13854     }
13855
13856   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13857
13858   /* Get list of l2 fib entries */
13859   M (L2_FIB_TABLE_DUMP, mp);
13860
13861   mp->bd_id = ntohl (bd_id);
13862   S (mp);
13863
13864   /* Use a control ping for synchronization */
13865   MPING (CONTROL_PING, mp_ping);
13866   S (mp_ping);
13867
13868   W (ret);
13869   return ret;
13870 }
13871
13872
13873 static int
13874 api_interface_name_renumber (vat_main_t * vam)
13875 {
13876   unformat_input_t *line_input = vam->input;
13877   vl_api_interface_name_renumber_t *mp;
13878   u32 sw_if_index = ~0;
13879   u32 new_show_dev_instance = ~0;
13880   int ret;
13881
13882   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13885                     &sw_if_index))
13886         ;
13887       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13888         ;
13889       else if (unformat (line_input, "new_show_dev_instance %d",
13890                          &new_show_dev_instance))
13891         ;
13892       else
13893         break;
13894     }
13895
13896   if (sw_if_index == ~0)
13897     {
13898       errmsg ("missing interface name or sw_if_index");
13899       return -99;
13900     }
13901
13902   if (new_show_dev_instance == ~0)
13903     {
13904       errmsg ("missing new_show_dev_instance");
13905       return -99;
13906     }
13907
13908   M (INTERFACE_NAME_RENUMBER, mp);
13909
13910   mp->sw_if_index = ntohl (sw_if_index);
13911   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13912
13913   S (mp);
13914   W (ret);
13915   return ret;
13916 }
13917
13918 static int
13919 api_ip_probe_neighbor (vat_main_t * vam)
13920 {
13921   unformat_input_t *i = vam->input;
13922   vl_api_ip_probe_neighbor_t *mp;
13923   vl_api_address_t dst_adr = { };
13924   u8 int_set = 0;
13925   u8 adr_set = 0;
13926   u32 sw_if_index;
13927   int ret;
13928
13929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13930     {
13931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13932         int_set = 1;
13933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13934         int_set = 1;
13935       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13936         adr_set = 1;
13937       else
13938         break;
13939     }
13940
13941   if (int_set == 0)
13942     {
13943       errmsg ("missing interface");
13944       return -99;
13945     }
13946
13947   if (adr_set == 0)
13948     {
13949       errmsg ("missing addresses");
13950       return -99;
13951     }
13952
13953   M (IP_PROBE_NEIGHBOR, mp);
13954
13955   mp->sw_if_index = ntohl (sw_if_index);
13956   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13957
13958   S (mp);
13959   W (ret);
13960   return ret;
13961 }
13962
13963 static int
13964 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13965 {
13966   unformat_input_t *i = vam->input;
13967   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13968   u8 mode = IP_SCAN_V46_NEIGHBORS;
13969   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13970   int ret;
13971
13972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13973     {
13974       if (unformat (i, "ip4"))
13975         mode = IP_SCAN_V4_NEIGHBORS;
13976       else if (unformat (i, "ip6"))
13977         mode = IP_SCAN_V6_NEIGHBORS;
13978       if (unformat (i, "both"))
13979         mode = IP_SCAN_V46_NEIGHBORS;
13980       else if (unformat (i, "disable"))
13981         mode = IP_SCAN_DISABLED;
13982       else if (unformat (i, "interval %d", &interval))
13983         ;
13984       else if (unformat (i, "max-time %d", &time))
13985         ;
13986       else if (unformat (i, "max-update %d", &update))
13987         ;
13988       else if (unformat (i, "delay %d", &delay))
13989         ;
13990       else if (unformat (i, "stale %d", &stale))
13991         ;
13992       else
13993         break;
13994     }
13995
13996   if (interval > 255)
13997     {
13998       errmsg ("interval cannot exceed 255 minutes.");
13999       return -99;
14000     }
14001   if (time > 255)
14002     {
14003       errmsg ("max-time cannot exceed 255 usec.");
14004       return -99;
14005     }
14006   if (update > 255)
14007     {
14008       errmsg ("max-update cannot exceed 255.");
14009       return -99;
14010     }
14011   if (delay > 255)
14012     {
14013       errmsg ("delay cannot exceed 255 msec.");
14014       return -99;
14015     }
14016   if (stale > 255)
14017     {
14018       errmsg ("stale cannot exceed 255 minutes.");
14019       return -99;
14020     }
14021
14022   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14023   mp->mode = mode;
14024   mp->scan_interval = interval;
14025   mp->max_proc_time = time;
14026   mp->max_update = update;
14027   mp->scan_int_delay = delay;
14028   mp->stale_threshold = stale;
14029
14030   S (mp);
14031   W (ret);
14032   return ret;
14033 }
14034
14035 static int
14036 api_want_ip4_arp_events (vat_main_t * vam)
14037 {
14038   unformat_input_t *line_input = vam->input;
14039   vl_api_want_ip4_arp_events_t *mp;
14040   ip4_address_t address;
14041   int address_set = 0;
14042   u32 enable_disable = 1;
14043   int ret;
14044
14045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14046     {
14047       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14048         address_set = 1;
14049       else if (unformat (line_input, "del"))
14050         enable_disable = 0;
14051       else
14052         break;
14053     }
14054
14055   if (address_set == 0)
14056     {
14057       errmsg ("missing addresses");
14058       return -99;
14059     }
14060
14061   M (WANT_IP4_ARP_EVENTS, mp);
14062   mp->enable_disable = enable_disable;
14063   mp->pid = htonl (getpid ());
14064   clib_memcpy (mp->ip, &address, sizeof (address));
14065
14066   S (mp);
14067   W (ret);
14068   return ret;
14069 }
14070
14071 static int
14072 api_want_ip6_nd_events (vat_main_t * vam)
14073 {
14074   unformat_input_t *line_input = vam->input;
14075   vl_api_want_ip6_nd_events_t *mp;
14076   vl_api_ip6_address_t address;
14077   int address_set = 0;
14078   u32 enable_disable = 1;
14079   int ret;
14080
14081   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14082     {
14083       if (unformat
14084           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14085         address_set = 1;
14086       else if (unformat (line_input, "del"))
14087         enable_disable = 0;
14088       else
14089         break;
14090     }
14091
14092   if (address_set == 0)
14093     {
14094       errmsg ("missing addresses");
14095       return -99;
14096     }
14097
14098   M (WANT_IP6_ND_EVENTS, mp);
14099   mp->enable_disable = enable_disable;
14100   mp->pid = htonl (getpid ());
14101   clib_memcpy (&mp->ip, &address, sizeof (address));
14102
14103   S (mp);
14104   W (ret);
14105   return ret;
14106 }
14107
14108 static int
14109 api_want_l2_macs_events (vat_main_t * vam)
14110 {
14111   unformat_input_t *line_input = vam->input;
14112   vl_api_want_l2_macs_events_t *mp;
14113   u8 enable_disable = 1;
14114   u32 scan_delay = 0;
14115   u32 max_macs_in_event = 0;
14116   u32 learn_limit = 0;
14117   int ret;
14118
14119   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14120     {
14121       if (unformat (line_input, "learn-limit %d", &learn_limit))
14122         ;
14123       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14124         ;
14125       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14126         ;
14127       else if (unformat (line_input, "disable"))
14128         enable_disable = 0;
14129       else
14130         break;
14131     }
14132
14133   M (WANT_L2_MACS_EVENTS, mp);
14134   mp->enable_disable = enable_disable;
14135   mp->pid = htonl (getpid ());
14136   mp->learn_limit = htonl (learn_limit);
14137   mp->scan_delay = (u8) scan_delay;
14138   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14139   S (mp);
14140   W (ret);
14141   return ret;
14142 }
14143
14144 static int
14145 api_input_acl_set_interface (vat_main_t * vam)
14146 {
14147   unformat_input_t *i = vam->input;
14148   vl_api_input_acl_set_interface_t *mp;
14149   u32 sw_if_index;
14150   int sw_if_index_set;
14151   u32 ip4_table_index = ~0;
14152   u32 ip6_table_index = ~0;
14153   u32 l2_table_index = ~0;
14154   u8 is_add = 1;
14155   int ret;
14156
14157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14158     {
14159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14160         sw_if_index_set = 1;
14161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14162         sw_if_index_set = 1;
14163       else if (unformat (i, "del"))
14164         is_add = 0;
14165       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14166         ;
14167       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14168         ;
14169       else if (unformat (i, "l2-table %d", &l2_table_index))
14170         ;
14171       else
14172         {
14173           clib_warning ("parse error '%U'", format_unformat_error, i);
14174           return -99;
14175         }
14176     }
14177
14178   if (sw_if_index_set == 0)
14179     {
14180       errmsg ("missing interface name or sw_if_index");
14181       return -99;
14182     }
14183
14184   M (INPUT_ACL_SET_INTERFACE, mp);
14185
14186   mp->sw_if_index = ntohl (sw_if_index);
14187   mp->ip4_table_index = ntohl (ip4_table_index);
14188   mp->ip6_table_index = ntohl (ip6_table_index);
14189   mp->l2_table_index = ntohl (l2_table_index);
14190   mp->is_add = is_add;
14191
14192   S (mp);
14193   W (ret);
14194   return ret;
14195 }
14196
14197 static int
14198 api_output_acl_set_interface (vat_main_t * vam)
14199 {
14200   unformat_input_t *i = vam->input;
14201   vl_api_output_acl_set_interface_t *mp;
14202   u32 sw_if_index;
14203   int sw_if_index_set;
14204   u32 ip4_table_index = ~0;
14205   u32 ip6_table_index = ~0;
14206   u32 l2_table_index = ~0;
14207   u8 is_add = 1;
14208   int ret;
14209
14210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14211     {
14212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14213         sw_if_index_set = 1;
14214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14215         sw_if_index_set = 1;
14216       else if (unformat (i, "del"))
14217         is_add = 0;
14218       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14219         ;
14220       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14221         ;
14222       else if (unformat (i, "l2-table %d", &l2_table_index))
14223         ;
14224       else
14225         {
14226           clib_warning ("parse error '%U'", format_unformat_error, i);
14227           return -99;
14228         }
14229     }
14230
14231   if (sw_if_index_set == 0)
14232     {
14233       errmsg ("missing interface name or sw_if_index");
14234       return -99;
14235     }
14236
14237   M (OUTPUT_ACL_SET_INTERFACE, mp);
14238
14239   mp->sw_if_index = ntohl (sw_if_index);
14240   mp->ip4_table_index = ntohl (ip4_table_index);
14241   mp->ip6_table_index = ntohl (ip6_table_index);
14242   mp->l2_table_index = ntohl (l2_table_index);
14243   mp->is_add = is_add;
14244
14245   S (mp);
14246   W (ret);
14247   return ret;
14248 }
14249
14250 static int
14251 api_ip_address_dump (vat_main_t * vam)
14252 {
14253   unformat_input_t *i = vam->input;
14254   vl_api_ip_address_dump_t *mp;
14255   vl_api_control_ping_t *mp_ping;
14256   u32 sw_if_index = ~0;
14257   u8 sw_if_index_set = 0;
14258   u8 ipv4_set = 0;
14259   u8 ipv6_set = 0;
14260   int ret;
14261
14262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14263     {
14264       if (unformat (i, "sw_if_index %d", &sw_if_index))
14265         sw_if_index_set = 1;
14266       else
14267         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14268         sw_if_index_set = 1;
14269       else if (unformat (i, "ipv4"))
14270         ipv4_set = 1;
14271       else if (unformat (i, "ipv6"))
14272         ipv6_set = 1;
14273       else
14274         break;
14275     }
14276
14277   if (ipv4_set && ipv6_set)
14278     {
14279       errmsg ("ipv4 and ipv6 flags cannot be both set");
14280       return -99;
14281     }
14282
14283   if ((!ipv4_set) && (!ipv6_set))
14284     {
14285       errmsg ("no ipv4 nor ipv6 flag set");
14286       return -99;
14287     }
14288
14289   if (sw_if_index_set == 0)
14290     {
14291       errmsg ("missing interface name or sw_if_index");
14292       return -99;
14293     }
14294
14295   vam->current_sw_if_index = sw_if_index;
14296   vam->is_ipv6 = ipv6_set;
14297
14298   M (IP_ADDRESS_DUMP, mp);
14299   mp->sw_if_index = ntohl (sw_if_index);
14300   mp->is_ipv6 = ipv6_set;
14301   S (mp);
14302
14303   /* Use a control ping for synchronization */
14304   MPING (CONTROL_PING, mp_ping);
14305   S (mp_ping);
14306
14307   W (ret);
14308   return ret;
14309 }
14310
14311 static int
14312 api_ip_dump (vat_main_t * vam)
14313 {
14314   vl_api_ip_dump_t *mp;
14315   vl_api_control_ping_t *mp_ping;
14316   unformat_input_t *in = vam->input;
14317   int ipv4_set = 0;
14318   int ipv6_set = 0;
14319   int is_ipv6;
14320   int i;
14321   int ret;
14322
14323   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14324     {
14325       if (unformat (in, "ipv4"))
14326         ipv4_set = 1;
14327       else if (unformat (in, "ipv6"))
14328         ipv6_set = 1;
14329       else
14330         break;
14331     }
14332
14333   if (ipv4_set && ipv6_set)
14334     {
14335       errmsg ("ipv4 and ipv6 flags cannot be both set");
14336       return -99;
14337     }
14338
14339   if ((!ipv4_set) && (!ipv6_set))
14340     {
14341       errmsg ("no ipv4 nor ipv6 flag set");
14342       return -99;
14343     }
14344
14345   is_ipv6 = ipv6_set;
14346   vam->is_ipv6 = is_ipv6;
14347
14348   /* free old data */
14349   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14350     {
14351       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14352     }
14353   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14354
14355   M (IP_DUMP, mp);
14356   mp->is_ipv6 = ipv6_set;
14357   S (mp);
14358
14359   /* Use a control ping for synchronization */
14360   MPING (CONTROL_PING, mp_ping);
14361   S (mp_ping);
14362
14363   W (ret);
14364   return ret;
14365 }
14366
14367 static int
14368 api_ipsec_spd_add_del (vat_main_t * vam)
14369 {
14370   unformat_input_t *i = vam->input;
14371   vl_api_ipsec_spd_add_del_t *mp;
14372   u32 spd_id = ~0;
14373   u8 is_add = 1;
14374   int ret;
14375
14376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14377     {
14378       if (unformat (i, "spd_id %d", &spd_id))
14379         ;
14380       else if (unformat (i, "del"))
14381         is_add = 0;
14382       else
14383         {
14384           clib_warning ("parse error '%U'", format_unformat_error, i);
14385           return -99;
14386         }
14387     }
14388   if (spd_id == ~0)
14389     {
14390       errmsg ("spd_id must be set");
14391       return -99;
14392     }
14393
14394   M (IPSEC_SPD_ADD_DEL, mp);
14395
14396   mp->spd_id = ntohl (spd_id);
14397   mp->is_add = is_add;
14398
14399   S (mp);
14400   W (ret);
14401   return ret;
14402 }
14403
14404 static int
14405 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14406 {
14407   unformat_input_t *i = vam->input;
14408   vl_api_ipsec_interface_add_del_spd_t *mp;
14409   u32 sw_if_index;
14410   u8 sw_if_index_set = 0;
14411   u32 spd_id = (u32) ~ 0;
14412   u8 is_add = 1;
14413   int ret;
14414
14415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14416     {
14417       if (unformat (i, "del"))
14418         is_add = 0;
14419       else if (unformat (i, "spd_id %d", &spd_id))
14420         ;
14421       else
14422         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14423         sw_if_index_set = 1;
14424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14425         sw_if_index_set = 1;
14426       else
14427         {
14428           clib_warning ("parse error '%U'", format_unformat_error, i);
14429           return -99;
14430         }
14431
14432     }
14433
14434   if (spd_id == (u32) ~ 0)
14435     {
14436       errmsg ("spd_id must be set");
14437       return -99;
14438     }
14439
14440   if (sw_if_index_set == 0)
14441     {
14442       errmsg ("missing interface name or sw_if_index");
14443       return -99;
14444     }
14445
14446   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14447
14448   mp->spd_id = ntohl (spd_id);
14449   mp->sw_if_index = ntohl (sw_if_index);
14450   mp->is_add = is_add;
14451
14452   S (mp);
14453   W (ret);
14454   return ret;
14455 }
14456
14457 static int
14458 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14459 {
14460   unformat_input_t *i = vam->input;
14461   vl_api_ipsec_spd_entry_add_del_t *mp;
14462   u8 is_add = 1, is_outbound = 0;
14463   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14464   i32 priority = 0;
14465   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14466   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14467   vl_api_address_t laddr_start = { }, laddr_stop =
14468   {
14469   }, raddr_start =
14470   {
14471   }, raddr_stop =
14472   {
14473   };
14474   int ret;
14475
14476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14477     {
14478       if (unformat (i, "del"))
14479         is_add = 0;
14480       if (unformat (i, "outbound"))
14481         is_outbound = 1;
14482       if (unformat (i, "inbound"))
14483         is_outbound = 0;
14484       else if (unformat (i, "spd_id %d", &spd_id))
14485         ;
14486       else if (unformat (i, "sa_id %d", &sa_id))
14487         ;
14488       else if (unformat (i, "priority %d", &priority))
14489         ;
14490       else if (unformat (i, "protocol %d", &protocol))
14491         ;
14492       else if (unformat (i, "lport_start %d", &lport_start))
14493         ;
14494       else if (unformat (i, "lport_stop %d", &lport_stop))
14495         ;
14496       else if (unformat (i, "rport_start %d", &rport_start))
14497         ;
14498       else if (unformat (i, "rport_stop %d", &rport_stop))
14499         ;
14500       else if (unformat (i, "laddr_start %U",
14501                          unformat_vl_api_address, &laddr_start))
14502         ;
14503       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14504                          &laddr_stop))
14505         ;
14506       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14507                          &raddr_start))
14508         ;
14509       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14510                          &raddr_stop))
14511         ;
14512       else
14513         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14514         {
14515           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14516             {
14517               clib_warning ("unsupported action: 'resolve'");
14518               return -99;
14519             }
14520         }
14521       else
14522         {
14523           clib_warning ("parse error '%U'", format_unformat_error, i);
14524           return -99;
14525         }
14526
14527     }
14528
14529   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14530
14531   mp->is_add = is_add;
14532
14533   mp->entry.spd_id = ntohl (spd_id);
14534   mp->entry.priority = ntohl (priority);
14535   mp->entry.is_outbound = is_outbound;
14536
14537   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14538                sizeof (vl_api_address_t));
14539   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14540                sizeof (vl_api_address_t));
14541   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14542                sizeof (vl_api_address_t));
14543   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14544                sizeof (vl_api_address_t));
14545
14546   mp->entry.protocol = (u8) protocol;
14547   mp->entry.local_port_start = ntohs ((u16) lport_start);
14548   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14549   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14550   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14551   mp->entry.policy = (u8) policy;
14552   mp->entry.sa_id = ntohl (sa_id);
14553
14554   S (mp);
14555   W (ret);
14556   return ret;
14557 }
14558
14559 static int
14560 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14561 {
14562   unformat_input_t *i = vam->input;
14563   vl_api_ipsec_sad_entry_add_del_t *mp;
14564   u32 sad_id = 0, spi = 0;
14565   u8 *ck = 0, *ik = 0;
14566   u8 is_add = 1;
14567
14568   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14569   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14570   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14571   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14572   vl_api_address_t tun_src, tun_dst;
14573   int ret;
14574
14575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14576     {
14577       if (unformat (i, "del"))
14578         is_add = 0;
14579       else if (unformat (i, "sad_id %d", &sad_id))
14580         ;
14581       else if (unformat (i, "spi %d", &spi))
14582         ;
14583       else if (unformat (i, "esp"))
14584         protocol = IPSEC_API_PROTO_ESP;
14585       else
14586         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14587         {
14588           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14589           if (ADDRESS_IP6 == tun_src.af)
14590             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14591         }
14592       else
14593         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14594         {
14595           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14596           if (ADDRESS_IP6 == tun_src.af)
14597             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14598         }
14599       else
14600         if (unformat (i, "crypto_alg %U",
14601                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14602         ;
14603       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14604         ;
14605       else if (unformat (i, "integ_alg %U",
14606                          unformat_ipsec_api_integ_alg, &integ_alg))
14607         ;
14608       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14609         ;
14610       else
14611         {
14612           clib_warning ("parse error '%U'", format_unformat_error, i);
14613           return -99;
14614         }
14615
14616     }
14617
14618   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14619
14620   mp->is_add = is_add;
14621   mp->entry.sad_id = ntohl (sad_id);
14622   mp->entry.protocol = protocol;
14623   mp->entry.spi = ntohl (spi);
14624   mp->entry.flags = flags;
14625
14626   mp->entry.crypto_algorithm = crypto_alg;
14627   mp->entry.integrity_algorithm = integ_alg;
14628   mp->entry.crypto_key.length = vec_len (ck);
14629   mp->entry.integrity_key.length = vec_len (ik);
14630
14631   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14632     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14633
14634   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14635     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14636
14637   if (ck)
14638     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14639   if (ik)
14640     clib_memcpy (mp->entry.integrity_key.data, ik,
14641                  mp->entry.integrity_key.length);
14642
14643   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14644     {
14645       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14646                    sizeof (mp->entry.tunnel_src));
14647       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14648                    sizeof (mp->entry.tunnel_dst));
14649     }
14650
14651   S (mp);
14652   W (ret);
14653   return ret;
14654 }
14655
14656 static int
14657 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14658 {
14659   unformat_input_t *i = vam->input;
14660   vl_api_ipsec_tunnel_if_add_del_t *mp;
14661   u32 local_spi = 0, remote_spi = 0;
14662   u32 crypto_alg = 0, integ_alg = 0;
14663   u8 *lck = NULL, *rck = NULL;
14664   u8 *lik = NULL, *rik = NULL;
14665   vl_api_address_t local_ip = { 0 };
14666   vl_api_address_t remote_ip = { 0 };
14667   f64 before = 0;
14668   u8 is_add = 1;
14669   u8 esn = 0;
14670   u8 anti_replay = 0;
14671   u8 renumber = 0;
14672   u32 instance = ~0;
14673   u32 count = 1, jj;
14674   int ret = -1;
14675
14676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14677     {
14678       if (unformat (i, "del"))
14679         is_add = 0;
14680       else if (unformat (i, "esn"))
14681         esn = 1;
14682       else if (unformat (i, "anti-replay"))
14683         anti_replay = 1;
14684       else if (unformat (i, "count %d", &count))
14685         ;
14686       else if (unformat (i, "local_spi %d", &local_spi))
14687         ;
14688       else if (unformat (i, "remote_spi %d", &remote_spi))
14689         ;
14690       else
14691         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14692         ;
14693       else
14694         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14695         ;
14696       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14697         ;
14698       else
14699         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14700         ;
14701       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14702         ;
14703       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14704         ;
14705       else
14706         if (unformat
14707             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14708         {
14709           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14710             {
14711               errmsg ("unsupported crypto-alg: '%U'\n",
14712                       format_ipsec_crypto_alg, crypto_alg);
14713               return -99;
14714             }
14715         }
14716       else
14717         if (unformat
14718             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14719         {
14720           if (integ_alg >= IPSEC_INTEG_N_ALG)
14721             {
14722               errmsg ("unsupported integ-alg: '%U'\n",
14723                       format_ipsec_integ_alg, integ_alg);
14724               return -99;
14725             }
14726         }
14727       else if (unformat (i, "instance %u", &instance))
14728         renumber = 1;
14729       else
14730         {
14731           errmsg ("parse error '%U'\n", format_unformat_error, i);
14732           return -99;
14733         }
14734     }
14735
14736   if (count > 1)
14737     {
14738       /* Turn on async mode */
14739       vam->async_mode = 1;
14740       vam->async_errors = 0;
14741       before = vat_time_now (vam);
14742     }
14743
14744   for (jj = 0; jj < count; jj++)
14745     {
14746       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14747
14748       mp->is_add = is_add;
14749       mp->esn = esn;
14750       mp->anti_replay = anti_replay;
14751
14752       if (jj > 0)
14753         increment_address (&remote_ip);
14754
14755       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14756       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14757
14758       mp->local_spi = htonl (local_spi + jj);
14759       mp->remote_spi = htonl (remote_spi + jj);
14760       mp->crypto_alg = (u8) crypto_alg;
14761
14762       mp->local_crypto_key_len = 0;
14763       if (lck)
14764         {
14765           mp->local_crypto_key_len = vec_len (lck);
14766           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14767             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14768           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14769         }
14770
14771       mp->remote_crypto_key_len = 0;
14772       if (rck)
14773         {
14774           mp->remote_crypto_key_len = vec_len (rck);
14775           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14776             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14777           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14778         }
14779
14780       mp->integ_alg = (u8) integ_alg;
14781
14782       mp->local_integ_key_len = 0;
14783       if (lik)
14784         {
14785           mp->local_integ_key_len = vec_len (lik);
14786           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14787             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14788           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14789         }
14790
14791       mp->remote_integ_key_len = 0;
14792       if (rik)
14793         {
14794           mp->remote_integ_key_len = vec_len (rik);
14795           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14796             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14797           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14798         }
14799
14800       if (renumber)
14801         {
14802           mp->renumber = renumber;
14803           mp->show_instance = ntohl (instance);
14804         }
14805       S (mp);
14806     }
14807
14808   /* When testing multiple add/del ops, use a control-ping to sync */
14809   if (count > 1)
14810     {
14811       vl_api_control_ping_t *mp_ping;
14812       f64 after;
14813       f64 timeout;
14814
14815       /* Shut off async mode */
14816       vam->async_mode = 0;
14817
14818       MPING (CONTROL_PING, mp_ping);
14819       S (mp_ping);
14820
14821       timeout = vat_time_now (vam) + 1.0;
14822       while (vat_time_now (vam) < timeout)
14823         if (vam->result_ready == 1)
14824           goto out;
14825       vam->retval = -99;
14826
14827     out:
14828       if (vam->retval == -99)
14829         errmsg ("timeout");
14830
14831       if (vam->async_errors > 0)
14832         {
14833           errmsg ("%d asynchronous errors", vam->async_errors);
14834           vam->retval = -98;
14835         }
14836       vam->async_errors = 0;
14837       after = vat_time_now (vam);
14838
14839       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14840       if (jj > 0)
14841         count = jj;
14842
14843       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14844              count, after - before, count / (after - before));
14845     }
14846   else
14847     {
14848       /* Wait for a reply... */
14849       W (ret);
14850       return ret;
14851     }
14852
14853   return ret;
14854 }
14855
14856 static void
14857 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14858 {
14859   vat_main_t *vam = &vat_main;
14860
14861   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14862          "crypto_key %U integ_alg %u integ_key %U flags %x "
14863          "tunnel_src_addr %U tunnel_dst_addr %U "
14864          "salt %u seq_outbound %lu last_seq_inbound %lu "
14865          "replay_window %lu\n",
14866          ntohl (mp->entry.sad_id),
14867          ntohl (mp->sw_if_index),
14868          ntohl (mp->entry.spi),
14869          ntohl (mp->entry.protocol),
14870          ntohl (mp->entry.crypto_algorithm),
14871          format_hex_bytes, mp->entry.crypto_key.data,
14872          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14873          format_hex_bytes, mp->entry.integrity_key.data,
14874          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14875          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14876          &mp->entry.tunnel_dst, ntohl (mp->salt),
14877          clib_net_to_host_u64 (mp->seq_outbound),
14878          clib_net_to_host_u64 (mp->last_seq_inbound),
14879          clib_net_to_host_u64 (mp->replay_window));
14880 }
14881
14882 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14883 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14884
14885 static void vl_api_ipsec_sa_details_t_handler_json
14886   (vl_api_ipsec_sa_details_t * mp)
14887 {
14888   vat_main_t *vam = &vat_main;
14889   vat_json_node_t *node = NULL;
14890   vl_api_ipsec_sad_flags_t flags;
14891
14892   if (VAT_JSON_ARRAY != vam->json_tree.type)
14893     {
14894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14895       vat_json_init_array (&vam->json_tree);
14896     }
14897   node = vat_json_array_add (&vam->json_tree);
14898
14899   vat_json_init_object (node);
14900   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14901   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14902   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14903   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14904   vat_json_object_add_uint (node, "crypto_alg",
14905                             ntohl (mp->entry.crypto_algorithm));
14906   vat_json_object_add_uint (node, "integ_alg",
14907                             ntohl (mp->entry.integrity_algorithm));
14908   flags = ntohl (mp->entry.flags);
14909   vat_json_object_add_uint (node, "use_esn",
14910                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14911   vat_json_object_add_uint (node, "use_anti_replay",
14912                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14913   vat_json_object_add_uint (node, "is_tunnel",
14914                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14915   vat_json_object_add_uint (node, "is_tunnel_ip6",
14916                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14917   vat_json_object_add_uint (node, "udp_encap",
14918                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14919   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14920                              mp->entry.crypto_key.length);
14921   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14922                              mp->entry.integrity_key.length);
14923   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14924   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14925   vat_json_object_add_uint (node, "replay_window",
14926                             clib_net_to_host_u64 (mp->replay_window));
14927 }
14928
14929 static int
14930 api_ipsec_sa_dump (vat_main_t * vam)
14931 {
14932   unformat_input_t *i = vam->input;
14933   vl_api_ipsec_sa_dump_t *mp;
14934   vl_api_control_ping_t *mp_ping;
14935   u32 sa_id = ~0;
14936   int ret;
14937
14938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (i, "sa_id %d", &sa_id))
14941         ;
14942       else
14943         {
14944           clib_warning ("parse error '%U'", format_unformat_error, i);
14945           return -99;
14946         }
14947     }
14948
14949   M (IPSEC_SA_DUMP, mp);
14950
14951   mp->sa_id = ntohl (sa_id);
14952
14953   S (mp);
14954
14955   /* Use a control ping for synchronization */
14956   M (CONTROL_PING, mp_ping);
14957   S (mp_ping);
14958
14959   W (ret);
14960   return ret;
14961 }
14962
14963 static int
14964 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14965 {
14966   unformat_input_t *i = vam->input;
14967   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14968   u32 sw_if_index = ~0;
14969   u32 sa_id = ~0;
14970   u8 is_outbound = (u8) ~ 0;
14971   int ret;
14972
14973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14976         ;
14977       else if (unformat (i, "sa_id %d", &sa_id))
14978         ;
14979       else if (unformat (i, "outbound"))
14980         is_outbound = 1;
14981       else if (unformat (i, "inbound"))
14982         is_outbound = 0;
14983       else
14984         {
14985           clib_warning ("parse error '%U'", format_unformat_error, i);
14986           return -99;
14987         }
14988     }
14989
14990   if (sw_if_index == ~0)
14991     {
14992       errmsg ("interface must be specified");
14993       return -99;
14994     }
14995
14996   if (sa_id == ~0)
14997     {
14998       errmsg ("SA ID must be specified");
14999       return -99;
15000     }
15001
15002   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15003
15004   mp->sw_if_index = htonl (sw_if_index);
15005   mp->sa_id = htonl (sa_id);
15006   mp->is_outbound = is_outbound;
15007
15008   S (mp);
15009   W (ret);
15010
15011   return ret;
15012 }
15013
15014 static int
15015 api_get_first_msg_id (vat_main_t * vam)
15016 {
15017   vl_api_get_first_msg_id_t *mp;
15018   unformat_input_t *i = vam->input;
15019   u8 *name;
15020   u8 name_set = 0;
15021   int ret;
15022
15023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15024     {
15025       if (unformat (i, "client %s", &name))
15026         name_set = 1;
15027       else
15028         break;
15029     }
15030
15031   if (name_set == 0)
15032     {
15033       errmsg ("missing client name");
15034       return -99;
15035     }
15036   vec_add1 (name, 0);
15037
15038   if (vec_len (name) > 63)
15039     {
15040       errmsg ("client name too long");
15041       return -99;
15042     }
15043
15044   M (GET_FIRST_MSG_ID, mp);
15045   clib_memcpy (mp->name, name, vec_len (name));
15046   S (mp);
15047   W (ret);
15048   return ret;
15049 }
15050
15051 static int
15052 api_cop_interface_enable_disable (vat_main_t * vam)
15053 {
15054   unformat_input_t *line_input = vam->input;
15055   vl_api_cop_interface_enable_disable_t *mp;
15056   u32 sw_if_index = ~0;
15057   u8 enable_disable = 1;
15058   int ret;
15059
15060   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15061     {
15062       if (unformat (line_input, "disable"))
15063         enable_disable = 0;
15064       if (unformat (line_input, "enable"))
15065         enable_disable = 1;
15066       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15067                          vam, &sw_if_index))
15068         ;
15069       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15070         ;
15071       else
15072         break;
15073     }
15074
15075   if (sw_if_index == ~0)
15076     {
15077       errmsg ("missing interface name or sw_if_index");
15078       return -99;
15079     }
15080
15081   /* Construct the API message */
15082   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15083   mp->sw_if_index = ntohl (sw_if_index);
15084   mp->enable_disable = enable_disable;
15085
15086   /* send it... */
15087   S (mp);
15088   /* Wait for the reply */
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_cop_whitelist_enable_disable (vat_main_t * vam)
15095 {
15096   unformat_input_t *line_input = vam->input;
15097   vl_api_cop_whitelist_enable_disable_t *mp;
15098   u32 sw_if_index = ~0;
15099   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15100   u32 fib_id = 0;
15101   int ret;
15102
15103   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15104     {
15105       if (unformat (line_input, "ip4"))
15106         ip4 = 1;
15107       else if (unformat (line_input, "ip6"))
15108         ip6 = 1;
15109       else if (unformat (line_input, "default"))
15110         default_cop = 1;
15111       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15112                          vam, &sw_if_index))
15113         ;
15114       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15115         ;
15116       else if (unformat (line_input, "fib-id %d", &fib_id))
15117         ;
15118       else
15119         break;
15120     }
15121
15122   if (sw_if_index == ~0)
15123     {
15124       errmsg ("missing interface name or sw_if_index");
15125       return -99;
15126     }
15127
15128   /* Construct the API message */
15129   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15130   mp->sw_if_index = ntohl (sw_if_index);
15131   mp->fib_id = ntohl (fib_id);
15132   mp->ip4 = ip4;
15133   mp->ip6 = ip6;
15134   mp->default_cop = default_cop;
15135
15136   /* send it... */
15137   S (mp);
15138   /* Wait for the reply */
15139   W (ret);
15140   return ret;
15141 }
15142
15143 static int
15144 api_get_node_graph (vat_main_t * vam)
15145 {
15146   vl_api_get_node_graph_t *mp;
15147   int ret;
15148
15149   M (GET_NODE_GRAPH, mp);
15150
15151   /* send it... */
15152   S (mp);
15153   /* Wait for the reply */
15154   W (ret);
15155   return ret;
15156 }
15157
15158 /* *INDENT-OFF* */
15159 /** Used for parsing LISP eids */
15160 typedef CLIB_PACKED(struct{
15161   u8 addr[16];   /**< eid address */
15162   u32 len;       /**< prefix length if IP */
15163   u8 type;      /**< type of eid */
15164 }) lisp_eid_vat_t;
15165 /* *INDENT-ON* */
15166
15167 static uword
15168 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15169 {
15170   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15171
15172   clib_memset (a, 0, sizeof (a[0]));
15173
15174   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15175     {
15176       a->type = 0;              /* ipv4 type */
15177     }
15178   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15179     {
15180       a->type = 1;              /* ipv6 type */
15181     }
15182   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15183     {
15184       a->type = 2;              /* mac type */
15185     }
15186   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15187     {
15188       a->type = 3;              /* NSH type */
15189       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15190       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15191     }
15192   else
15193     {
15194       return 0;
15195     }
15196
15197   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15198     {
15199       return 0;
15200     }
15201
15202   return 1;
15203 }
15204
15205 static int
15206 lisp_eid_size_vat (u8 type)
15207 {
15208   switch (type)
15209     {
15210     case 0:
15211       return 4;
15212     case 1:
15213       return 16;
15214     case 2:
15215       return 6;
15216     case 3:
15217       return 5;
15218     }
15219   return 0;
15220 }
15221
15222 static void
15223 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15224 {
15225   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15226 }
15227
15228 static int
15229 api_one_add_del_locator_set (vat_main_t * vam)
15230 {
15231   unformat_input_t *input = vam->input;
15232   vl_api_one_add_del_locator_set_t *mp;
15233   u8 is_add = 1;
15234   u8 *locator_set_name = NULL;
15235   u8 locator_set_name_set = 0;
15236   vl_api_local_locator_t locator, *locators = 0;
15237   u32 sw_if_index, priority, weight;
15238   u32 data_len = 0;
15239
15240   int ret;
15241   /* Parse args required to build the message */
15242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15243     {
15244       if (unformat (input, "del"))
15245         {
15246           is_add = 0;
15247         }
15248       else if (unformat (input, "locator-set %s", &locator_set_name))
15249         {
15250           locator_set_name_set = 1;
15251         }
15252       else if (unformat (input, "sw_if_index %u p %u w %u",
15253                          &sw_if_index, &priority, &weight))
15254         {
15255           locator.sw_if_index = htonl (sw_if_index);
15256           locator.priority = priority;
15257           locator.weight = weight;
15258           vec_add1 (locators, locator);
15259         }
15260       else
15261         if (unformat
15262             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15263              &sw_if_index, &priority, &weight))
15264         {
15265           locator.sw_if_index = htonl (sw_if_index);
15266           locator.priority = priority;
15267           locator.weight = weight;
15268           vec_add1 (locators, locator);
15269         }
15270       else
15271         break;
15272     }
15273
15274   if (locator_set_name_set == 0)
15275     {
15276       errmsg ("missing locator-set name");
15277       vec_free (locators);
15278       return -99;
15279     }
15280
15281   if (vec_len (locator_set_name) > 64)
15282     {
15283       errmsg ("locator-set name too long");
15284       vec_free (locator_set_name);
15285       vec_free (locators);
15286       return -99;
15287     }
15288   vec_add1 (locator_set_name, 0);
15289
15290   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15291
15292   /* Construct the API message */
15293   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15294
15295   mp->is_add = is_add;
15296   clib_memcpy (mp->locator_set_name, locator_set_name,
15297                vec_len (locator_set_name));
15298   vec_free (locator_set_name);
15299
15300   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15301   if (locators)
15302     clib_memcpy (mp->locators, locators, data_len);
15303   vec_free (locators);
15304
15305   /* send it... */
15306   S (mp);
15307
15308   /* Wait for a reply... */
15309   W (ret);
15310   return ret;
15311 }
15312
15313 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15314
15315 static int
15316 api_one_add_del_locator (vat_main_t * vam)
15317 {
15318   unformat_input_t *input = vam->input;
15319   vl_api_one_add_del_locator_t *mp;
15320   u32 tmp_if_index = ~0;
15321   u32 sw_if_index = ~0;
15322   u8 sw_if_index_set = 0;
15323   u8 sw_if_index_if_name_set = 0;
15324   u32 priority = ~0;
15325   u8 priority_set = 0;
15326   u32 weight = ~0;
15327   u8 weight_set = 0;
15328   u8 is_add = 1;
15329   u8 *locator_set_name = NULL;
15330   u8 locator_set_name_set = 0;
15331   int ret;
15332
15333   /* Parse args required to build the message */
15334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15335     {
15336       if (unformat (input, "del"))
15337         {
15338           is_add = 0;
15339         }
15340       else if (unformat (input, "locator-set %s", &locator_set_name))
15341         {
15342           locator_set_name_set = 1;
15343         }
15344       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15345                          &tmp_if_index))
15346         {
15347           sw_if_index_if_name_set = 1;
15348           sw_if_index = tmp_if_index;
15349         }
15350       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15351         {
15352           sw_if_index_set = 1;
15353           sw_if_index = tmp_if_index;
15354         }
15355       else if (unformat (input, "p %d", &priority))
15356         {
15357           priority_set = 1;
15358         }
15359       else if (unformat (input, "w %d", &weight))
15360         {
15361           weight_set = 1;
15362         }
15363       else
15364         break;
15365     }
15366
15367   if (locator_set_name_set == 0)
15368     {
15369       errmsg ("missing locator-set name");
15370       return -99;
15371     }
15372
15373   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15374     {
15375       errmsg ("missing sw_if_index");
15376       vec_free (locator_set_name);
15377       return -99;
15378     }
15379
15380   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15381     {
15382       errmsg ("cannot use both params interface name and sw_if_index");
15383       vec_free (locator_set_name);
15384       return -99;
15385     }
15386
15387   if (priority_set == 0)
15388     {
15389       errmsg ("missing locator-set priority");
15390       vec_free (locator_set_name);
15391       return -99;
15392     }
15393
15394   if (weight_set == 0)
15395     {
15396       errmsg ("missing locator-set weight");
15397       vec_free (locator_set_name);
15398       return -99;
15399     }
15400
15401   if (vec_len (locator_set_name) > 64)
15402     {
15403       errmsg ("locator-set name too long");
15404       vec_free (locator_set_name);
15405       return -99;
15406     }
15407   vec_add1 (locator_set_name, 0);
15408
15409   /* Construct the API message */
15410   M (ONE_ADD_DEL_LOCATOR, mp);
15411
15412   mp->is_add = is_add;
15413   mp->sw_if_index = ntohl (sw_if_index);
15414   mp->priority = priority;
15415   mp->weight = weight;
15416   clib_memcpy (mp->locator_set_name, locator_set_name,
15417                vec_len (locator_set_name));
15418   vec_free (locator_set_name);
15419
15420   /* send it... */
15421   S (mp);
15422
15423   /* Wait for a reply... */
15424   W (ret);
15425   return ret;
15426 }
15427
15428 #define api_lisp_add_del_locator api_one_add_del_locator
15429
15430 uword
15431 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15432 {
15433   u32 *key_id = va_arg (*args, u32 *);
15434   u8 *s = 0;
15435
15436   if (unformat (input, "%s", &s))
15437     {
15438       if (!strcmp ((char *) s, "sha1"))
15439         key_id[0] = HMAC_SHA_1_96;
15440       else if (!strcmp ((char *) s, "sha256"))
15441         key_id[0] = HMAC_SHA_256_128;
15442       else
15443         {
15444           clib_warning ("invalid key_id: '%s'", s);
15445           key_id[0] = HMAC_NO_KEY;
15446         }
15447     }
15448   else
15449     return 0;
15450
15451   vec_free (s);
15452   return 1;
15453 }
15454
15455 static int
15456 api_one_add_del_local_eid (vat_main_t * vam)
15457 {
15458   unformat_input_t *input = vam->input;
15459   vl_api_one_add_del_local_eid_t *mp;
15460   u8 is_add = 1;
15461   u8 eid_set = 0;
15462   lisp_eid_vat_t _eid, *eid = &_eid;
15463   u8 *locator_set_name = 0;
15464   u8 locator_set_name_set = 0;
15465   u32 vni = 0;
15466   u16 key_id = 0;
15467   u8 *key = 0;
15468   int ret;
15469
15470   /* Parse args required to build the message */
15471   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15472     {
15473       if (unformat (input, "del"))
15474         {
15475           is_add = 0;
15476         }
15477       else if (unformat (input, "vni %d", &vni))
15478         {
15479           ;
15480         }
15481       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15482         {
15483           eid_set = 1;
15484         }
15485       else if (unformat (input, "locator-set %s", &locator_set_name))
15486         {
15487           locator_set_name_set = 1;
15488         }
15489       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15490         ;
15491       else if (unformat (input, "secret-key %_%v%_", &key))
15492         ;
15493       else
15494         break;
15495     }
15496
15497   if (locator_set_name_set == 0)
15498     {
15499       errmsg ("missing locator-set name");
15500       return -99;
15501     }
15502
15503   if (0 == eid_set)
15504     {
15505       errmsg ("EID address not set!");
15506       vec_free (locator_set_name);
15507       return -99;
15508     }
15509
15510   if (key && (0 == key_id))
15511     {
15512       errmsg ("invalid key_id!");
15513       return -99;
15514     }
15515
15516   if (vec_len (key) > 64)
15517     {
15518       errmsg ("key too long");
15519       vec_free (key);
15520       return -99;
15521     }
15522
15523   if (vec_len (locator_set_name) > 64)
15524     {
15525       errmsg ("locator-set name too long");
15526       vec_free (locator_set_name);
15527       return -99;
15528     }
15529   vec_add1 (locator_set_name, 0);
15530
15531   /* Construct the API message */
15532   M (ONE_ADD_DEL_LOCAL_EID, mp);
15533
15534   mp->is_add = is_add;
15535   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15536   mp->eid_type = eid->type;
15537   mp->prefix_len = eid->len;
15538   mp->vni = clib_host_to_net_u32 (vni);
15539   mp->key_id = clib_host_to_net_u16 (key_id);
15540   clib_memcpy (mp->locator_set_name, locator_set_name,
15541                vec_len (locator_set_name));
15542   clib_memcpy (mp->key, key, vec_len (key));
15543
15544   vec_free (locator_set_name);
15545   vec_free (key);
15546
15547   /* send it... */
15548   S (mp);
15549
15550   /* Wait for a reply... */
15551   W (ret);
15552   return ret;
15553 }
15554
15555 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15556
15557 static int
15558 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15559 {
15560   u32 dp_table = 0, vni = 0;;
15561   unformat_input_t *input = vam->input;
15562   vl_api_gpe_add_del_fwd_entry_t *mp;
15563   u8 is_add = 1;
15564   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15565   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15566   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15567   u32 action = ~0, w;
15568   ip4_address_t rmt_rloc4, lcl_rloc4;
15569   ip6_address_t rmt_rloc6, lcl_rloc6;
15570   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15571   int ret;
15572
15573   clib_memset (&rloc, 0, sizeof (rloc));
15574
15575   /* Parse args required to build the message */
15576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15577     {
15578       if (unformat (input, "del"))
15579         is_add = 0;
15580       else if (unformat (input, "add"))
15581         is_add = 1;
15582       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15583         {
15584           rmt_eid_set = 1;
15585         }
15586       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15587         {
15588           lcl_eid_set = 1;
15589         }
15590       else if (unformat (input, "vrf %d", &dp_table))
15591         ;
15592       else if (unformat (input, "bd %d", &dp_table))
15593         ;
15594       else if (unformat (input, "vni %d", &vni))
15595         ;
15596       else if (unformat (input, "w %d", &w))
15597         {
15598           if (!curr_rloc)
15599             {
15600               errmsg ("No RLOC configured for setting priority/weight!");
15601               return -99;
15602             }
15603           curr_rloc->weight = w;
15604         }
15605       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15606                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15607         {
15608           rloc.is_ip4 = 1;
15609
15610           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15611           rloc.weight = 0;
15612           vec_add1 (lcl_locs, rloc);
15613
15614           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15615           vec_add1 (rmt_locs, rloc);
15616           /* weight saved in rmt loc */
15617           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15618         }
15619       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15620                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15621         {
15622           rloc.is_ip4 = 0;
15623           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15624           rloc.weight = 0;
15625           vec_add1 (lcl_locs, rloc);
15626
15627           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15628           vec_add1 (rmt_locs, rloc);
15629           /* weight saved in rmt loc */
15630           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15631         }
15632       else if (unformat (input, "action %d", &action))
15633         {
15634           ;
15635         }
15636       else
15637         {
15638           clib_warning ("parse error '%U'", format_unformat_error, input);
15639           return -99;
15640         }
15641     }
15642
15643   if (!rmt_eid_set)
15644     {
15645       errmsg ("remote eid addresses not set");
15646       return -99;
15647     }
15648
15649   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15650     {
15651       errmsg ("eid types don't match");
15652       return -99;
15653     }
15654
15655   if (0 == rmt_locs && (u32) ~ 0 == action)
15656     {
15657       errmsg ("action not set for negative mapping");
15658       return -99;
15659     }
15660
15661   /* Construct the API message */
15662   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15663       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15664
15665   mp->is_add = is_add;
15666   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15667   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15668   mp->eid_type = rmt_eid->type;
15669   mp->dp_table = clib_host_to_net_u32 (dp_table);
15670   mp->vni = clib_host_to_net_u32 (vni);
15671   mp->rmt_len = rmt_eid->len;
15672   mp->lcl_len = lcl_eid->len;
15673   mp->action = action;
15674
15675   if (0 != rmt_locs && 0 != lcl_locs)
15676     {
15677       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15678       clib_memcpy (mp->locs, lcl_locs,
15679                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15680
15681       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15682       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15683                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15684     }
15685   vec_free (lcl_locs);
15686   vec_free (rmt_locs);
15687
15688   /* send it... */
15689   S (mp);
15690
15691   /* Wait for a reply... */
15692   W (ret);
15693   return ret;
15694 }
15695
15696 static int
15697 api_one_add_del_map_server (vat_main_t * vam)
15698 {
15699   unformat_input_t *input = vam->input;
15700   vl_api_one_add_del_map_server_t *mp;
15701   u8 is_add = 1;
15702   u8 ipv4_set = 0;
15703   u8 ipv6_set = 0;
15704   ip4_address_t ipv4;
15705   ip6_address_t ipv6;
15706   int ret;
15707
15708   /* Parse args required to build the message */
15709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15710     {
15711       if (unformat (input, "del"))
15712         {
15713           is_add = 0;
15714         }
15715       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15716         {
15717           ipv4_set = 1;
15718         }
15719       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15720         {
15721           ipv6_set = 1;
15722         }
15723       else
15724         break;
15725     }
15726
15727   if (ipv4_set && ipv6_set)
15728     {
15729       errmsg ("both eid v4 and v6 addresses set");
15730       return -99;
15731     }
15732
15733   if (!ipv4_set && !ipv6_set)
15734     {
15735       errmsg ("eid addresses not set");
15736       return -99;
15737     }
15738
15739   /* Construct the API message */
15740   M (ONE_ADD_DEL_MAP_SERVER, mp);
15741
15742   mp->is_add = is_add;
15743   if (ipv6_set)
15744     {
15745       mp->is_ipv6 = 1;
15746       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15747     }
15748   else
15749     {
15750       mp->is_ipv6 = 0;
15751       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15752     }
15753
15754   /* send it... */
15755   S (mp);
15756
15757   /* Wait for a reply... */
15758   W (ret);
15759   return ret;
15760 }
15761
15762 #define api_lisp_add_del_map_server api_one_add_del_map_server
15763
15764 static int
15765 api_one_add_del_map_resolver (vat_main_t * vam)
15766 {
15767   unformat_input_t *input = vam->input;
15768   vl_api_one_add_del_map_resolver_t *mp;
15769   u8 is_add = 1;
15770   u8 ipv4_set = 0;
15771   u8 ipv6_set = 0;
15772   ip4_address_t ipv4;
15773   ip6_address_t ipv6;
15774   int ret;
15775
15776   /* Parse args required to build the message */
15777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15778     {
15779       if (unformat (input, "del"))
15780         {
15781           is_add = 0;
15782         }
15783       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15784         {
15785           ipv4_set = 1;
15786         }
15787       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15788         {
15789           ipv6_set = 1;
15790         }
15791       else
15792         break;
15793     }
15794
15795   if (ipv4_set && ipv6_set)
15796     {
15797       errmsg ("both eid v4 and v6 addresses set");
15798       return -99;
15799     }
15800
15801   if (!ipv4_set && !ipv6_set)
15802     {
15803       errmsg ("eid addresses not set");
15804       return -99;
15805     }
15806
15807   /* Construct the API message */
15808   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15809
15810   mp->is_add = is_add;
15811   if (ipv6_set)
15812     {
15813       mp->is_ipv6 = 1;
15814       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15815     }
15816   else
15817     {
15818       mp->is_ipv6 = 0;
15819       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15820     }
15821
15822   /* send it... */
15823   S (mp);
15824
15825   /* Wait for a reply... */
15826   W (ret);
15827   return ret;
15828 }
15829
15830 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15831
15832 static int
15833 api_lisp_gpe_enable_disable (vat_main_t * vam)
15834 {
15835   unformat_input_t *input = vam->input;
15836   vl_api_gpe_enable_disable_t *mp;
15837   u8 is_set = 0;
15838   u8 is_en = 1;
15839   int ret;
15840
15841   /* Parse args required to build the message */
15842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15843     {
15844       if (unformat (input, "enable"))
15845         {
15846           is_set = 1;
15847           is_en = 1;
15848         }
15849       else if (unformat (input, "disable"))
15850         {
15851           is_set = 1;
15852           is_en = 0;
15853         }
15854       else
15855         break;
15856     }
15857
15858   if (is_set == 0)
15859     {
15860       errmsg ("Value not set");
15861       return -99;
15862     }
15863
15864   /* Construct the API message */
15865   M (GPE_ENABLE_DISABLE, mp);
15866
15867   mp->is_en = is_en;
15868
15869   /* send it... */
15870   S (mp);
15871
15872   /* Wait for a reply... */
15873   W (ret);
15874   return ret;
15875 }
15876
15877 static int
15878 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15879 {
15880   unformat_input_t *input = vam->input;
15881   vl_api_one_rloc_probe_enable_disable_t *mp;
15882   u8 is_set = 0;
15883   u8 is_en = 0;
15884   int ret;
15885
15886   /* Parse args required to build the message */
15887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15888     {
15889       if (unformat (input, "enable"))
15890         {
15891           is_set = 1;
15892           is_en = 1;
15893         }
15894       else if (unformat (input, "disable"))
15895         is_set = 1;
15896       else
15897         break;
15898     }
15899
15900   if (!is_set)
15901     {
15902       errmsg ("Value not set");
15903       return -99;
15904     }
15905
15906   /* Construct the API message */
15907   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15908
15909   mp->is_enabled = is_en;
15910
15911   /* send it... */
15912   S (mp);
15913
15914   /* Wait for a reply... */
15915   W (ret);
15916   return ret;
15917 }
15918
15919 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15920
15921 static int
15922 api_one_map_register_enable_disable (vat_main_t * vam)
15923 {
15924   unformat_input_t *input = vam->input;
15925   vl_api_one_map_register_enable_disable_t *mp;
15926   u8 is_set = 0;
15927   u8 is_en = 0;
15928   int ret;
15929
15930   /* Parse args required to build the message */
15931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15932     {
15933       if (unformat (input, "enable"))
15934         {
15935           is_set = 1;
15936           is_en = 1;
15937         }
15938       else if (unformat (input, "disable"))
15939         is_set = 1;
15940       else
15941         break;
15942     }
15943
15944   if (!is_set)
15945     {
15946       errmsg ("Value not set");
15947       return -99;
15948     }
15949
15950   /* Construct the API message */
15951   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15952
15953   mp->is_enabled = is_en;
15954
15955   /* send it... */
15956   S (mp);
15957
15958   /* Wait for a reply... */
15959   W (ret);
15960   return ret;
15961 }
15962
15963 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15964
15965 static int
15966 api_one_enable_disable (vat_main_t * vam)
15967 {
15968   unformat_input_t *input = vam->input;
15969   vl_api_one_enable_disable_t *mp;
15970   u8 is_set = 0;
15971   u8 is_en = 0;
15972   int ret;
15973
15974   /* Parse args required to build the message */
15975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15976     {
15977       if (unformat (input, "enable"))
15978         {
15979           is_set = 1;
15980           is_en = 1;
15981         }
15982       else if (unformat (input, "disable"))
15983         {
15984           is_set = 1;
15985         }
15986       else
15987         break;
15988     }
15989
15990   if (!is_set)
15991     {
15992       errmsg ("Value not set");
15993       return -99;
15994     }
15995
15996   /* Construct the API message */
15997   M (ONE_ENABLE_DISABLE, mp);
15998
15999   mp->is_en = is_en;
16000
16001   /* send it... */
16002   S (mp);
16003
16004   /* Wait for a reply... */
16005   W (ret);
16006   return ret;
16007 }
16008
16009 #define api_lisp_enable_disable api_one_enable_disable
16010
16011 static int
16012 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16013 {
16014   unformat_input_t *input = vam->input;
16015   vl_api_one_enable_disable_xtr_mode_t *mp;
16016   u8 is_set = 0;
16017   u8 is_en = 0;
16018   int ret;
16019
16020   /* Parse args required to build the message */
16021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16022     {
16023       if (unformat (input, "enable"))
16024         {
16025           is_set = 1;
16026           is_en = 1;
16027         }
16028       else if (unformat (input, "disable"))
16029         {
16030           is_set = 1;
16031         }
16032       else
16033         break;
16034     }
16035
16036   if (!is_set)
16037     {
16038       errmsg ("Value not set");
16039       return -99;
16040     }
16041
16042   /* Construct the API message */
16043   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16044
16045   mp->is_en = is_en;
16046
16047   /* send it... */
16048   S (mp);
16049
16050   /* Wait for a reply... */
16051   W (ret);
16052   return ret;
16053 }
16054
16055 static int
16056 api_one_show_xtr_mode (vat_main_t * vam)
16057 {
16058   vl_api_one_show_xtr_mode_t *mp;
16059   int ret;
16060
16061   /* Construct the API message */
16062   M (ONE_SHOW_XTR_MODE, mp);
16063
16064   /* send it... */
16065   S (mp);
16066
16067   /* Wait for a reply... */
16068   W (ret);
16069   return ret;
16070 }
16071
16072 static int
16073 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16074 {
16075   unformat_input_t *input = vam->input;
16076   vl_api_one_enable_disable_pitr_mode_t *mp;
16077   u8 is_set = 0;
16078   u8 is_en = 0;
16079   int ret;
16080
16081   /* Parse args required to build the message */
16082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16083     {
16084       if (unformat (input, "enable"))
16085         {
16086           is_set = 1;
16087           is_en = 1;
16088         }
16089       else if (unformat (input, "disable"))
16090         {
16091           is_set = 1;
16092         }
16093       else
16094         break;
16095     }
16096
16097   if (!is_set)
16098     {
16099       errmsg ("Value not set");
16100       return -99;
16101     }
16102
16103   /* Construct the API message */
16104   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16105
16106   mp->is_en = is_en;
16107
16108   /* send it... */
16109   S (mp);
16110
16111   /* Wait for a reply... */
16112   W (ret);
16113   return ret;
16114 }
16115
16116 static int
16117 api_one_show_pitr_mode (vat_main_t * vam)
16118 {
16119   vl_api_one_show_pitr_mode_t *mp;
16120   int ret;
16121
16122   /* Construct the API message */
16123   M (ONE_SHOW_PITR_MODE, mp);
16124
16125   /* send it... */
16126   S (mp);
16127
16128   /* Wait for a reply... */
16129   W (ret);
16130   return ret;
16131 }
16132
16133 static int
16134 api_one_enable_disable_petr_mode (vat_main_t * vam)
16135 {
16136   unformat_input_t *input = vam->input;
16137   vl_api_one_enable_disable_petr_mode_t *mp;
16138   u8 is_set = 0;
16139   u8 is_en = 0;
16140   int ret;
16141
16142   /* Parse args required to build the message */
16143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16144     {
16145       if (unformat (input, "enable"))
16146         {
16147           is_set = 1;
16148           is_en = 1;
16149         }
16150       else if (unformat (input, "disable"))
16151         {
16152           is_set = 1;
16153         }
16154       else
16155         break;
16156     }
16157
16158   if (!is_set)
16159     {
16160       errmsg ("Value not set");
16161       return -99;
16162     }
16163
16164   /* Construct the API message */
16165   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16166
16167   mp->is_en = is_en;
16168
16169   /* send it... */
16170   S (mp);
16171
16172   /* Wait for a reply... */
16173   W (ret);
16174   return ret;
16175 }
16176
16177 static int
16178 api_one_show_petr_mode (vat_main_t * vam)
16179 {
16180   vl_api_one_show_petr_mode_t *mp;
16181   int ret;
16182
16183   /* Construct the API message */
16184   M (ONE_SHOW_PETR_MODE, mp);
16185
16186   /* send it... */
16187   S (mp);
16188
16189   /* Wait for a reply... */
16190   W (ret);
16191   return ret;
16192 }
16193
16194 static int
16195 api_show_one_map_register_state (vat_main_t * vam)
16196 {
16197   vl_api_show_one_map_register_state_t *mp;
16198   int ret;
16199
16200   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16201
16202   /* send */
16203   S (mp);
16204
16205   /* wait for reply */
16206   W (ret);
16207   return ret;
16208 }
16209
16210 #define api_show_lisp_map_register_state api_show_one_map_register_state
16211
16212 static int
16213 api_show_one_rloc_probe_state (vat_main_t * vam)
16214 {
16215   vl_api_show_one_rloc_probe_state_t *mp;
16216   int ret;
16217
16218   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16219
16220   /* send */
16221   S (mp);
16222
16223   /* wait for reply */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16229
16230 static int
16231 api_one_add_del_ndp_entry (vat_main_t * vam)
16232 {
16233   vl_api_one_add_del_ndp_entry_t *mp;
16234   unformat_input_t *input = vam->input;
16235   u8 is_add = 1;
16236   u8 mac_set = 0;
16237   u8 bd_set = 0;
16238   u8 ip_set = 0;
16239   u8 mac[6] = { 0, };
16240   u8 ip6[16] = { 0, };
16241   u32 bd = ~0;
16242   int ret;
16243
16244   /* Parse args required to build the message */
16245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16246     {
16247       if (unformat (input, "del"))
16248         is_add = 0;
16249       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16250         mac_set = 1;
16251       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16252         ip_set = 1;
16253       else if (unformat (input, "bd %d", &bd))
16254         bd_set = 1;
16255       else
16256         {
16257           errmsg ("parse error '%U'", format_unformat_error, input);
16258           return -99;
16259         }
16260     }
16261
16262   if (!bd_set || !ip_set || (!mac_set && is_add))
16263     {
16264       errmsg ("Missing BD, IP or MAC!");
16265       return -99;
16266     }
16267
16268   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16269   mp->is_add = is_add;
16270   clib_memcpy (mp->mac, mac, 6);
16271   mp->bd = clib_host_to_net_u32 (bd);
16272   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16273
16274   /* send */
16275   S (mp);
16276
16277   /* wait for reply */
16278   W (ret);
16279   return ret;
16280 }
16281
16282 static int
16283 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16284 {
16285   vl_api_one_add_del_l2_arp_entry_t *mp;
16286   unformat_input_t *input = vam->input;
16287   u8 is_add = 1;
16288   u8 mac_set = 0;
16289   u8 bd_set = 0;
16290   u8 ip_set = 0;
16291   u8 mac[6] = { 0, };
16292   u32 ip4 = 0, bd = ~0;
16293   int ret;
16294
16295   /* Parse args required to build the message */
16296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16297     {
16298       if (unformat (input, "del"))
16299         is_add = 0;
16300       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16301         mac_set = 1;
16302       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16303         ip_set = 1;
16304       else if (unformat (input, "bd %d", &bd))
16305         bd_set = 1;
16306       else
16307         {
16308           errmsg ("parse error '%U'", format_unformat_error, input);
16309           return -99;
16310         }
16311     }
16312
16313   if (!bd_set || !ip_set || (!mac_set && is_add))
16314     {
16315       errmsg ("Missing BD, IP or MAC!");
16316       return -99;
16317     }
16318
16319   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16320   mp->is_add = is_add;
16321   clib_memcpy (mp->mac, mac, 6);
16322   mp->bd = clib_host_to_net_u32 (bd);
16323   mp->ip4 = ip4;
16324
16325   /* send */
16326   S (mp);
16327
16328   /* wait for reply */
16329   W (ret);
16330   return ret;
16331 }
16332
16333 static int
16334 api_one_ndp_bd_get (vat_main_t * vam)
16335 {
16336   vl_api_one_ndp_bd_get_t *mp;
16337   int ret;
16338
16339   M (ONE_NDP_BD_GET, mp);
16340
16341   /* send */
16342   S (mp);
16343
16344   /* wait for reply */
16345   W (ret);
16346   return ret;
16347 }
16348
16349 static int
16350 api_one_ndp_entries_get (vat_main_t * vam)
16351 {
16352   vl_api_one_ndp_entries_get_t *mp;
16353   unformat_input_t *input = vam->input;
16354   u8 bd_set = 0;
16355   u32 bd = ~0;
16356   int ret;
16357
16358   /* Parse args required to build the message */
16359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (input, "bd %d", &bd))
16362         bd_set = 1;
16363       else
16364         {
16365           errmsg ("parse error '%U'", format_unformat_error, input);
16366           return -99;
16367         }
16368     }
16369
16370   if (!bd_set)
16371     {
16372       errmsg ("Expected bridge domain!");
16373       return -99;
16374     }
16375
16376   M (ONE_NDP_ENTRIES_GET, mp);
16377   mp->bd = clib_host_to_net_u32 (bd);
16378
16379   /* send */
16380   S (mp);
16381
16382   /* wait for reply */
16383   W (ret);
16384   return ret;
16385 }
16386
16387 static int
16388 api_one_l2_arp_bd_get (vat_main_t * vam)
16389 {
16390   vl_api_one_l2_arp_bd_get_t *mp;
16391   int ret;
16392
16393   M (ONE_L2_ARP_BD_GET, mp);
16394
16395   /* send */
16396   S (mp);
16397
16398   /* wait for reply */
16399   W (ret);
16400   return ret;
16401 }
16402
16403 static int
16404 api_one_l2_arp_entries_get (vat_main_t * vam)
16405 {
16406   vl_api_one_l2_arp_entries_get_t *mp;
16407   unformat_input_t *input = vam->input;
16408   u8 bd_set = 0;
16409   u32 bd = ~0;
16410   int ret;
16411
16412   /* Parse args required to build the message */
16413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (input, "bd %d", &bd))
16416         bd_set = 1;
16417       else
16418         {
16419           errmsg ("parse error '%U'", format_unformat_error, input);
16420           return -99;
16421         }
16422     }
16423
16424   if (!bd_set)
16425     {
16426       errmsg ("Expected bridge domain!");
16427       return -99;
16428     }
16429
16430   M (ONE_L2_ARP_ENTRIES_GET, mp);
16431   mp->bd = clib_host_to_net_u32 (bd);
16432
16433   /* send */
16434   S (mp);
16435
16436   /* wait for reply */
16437   W (ret);
16438   return ret;
16439 }
16440
16441 static int
16442 api_one_stats_enable_disable (vat_main_t * vam)
16443 {
16444   vl_api_one_stats_enable_disable_t *mp;
16445   unformat_input_t *input = vam->input;
16446   u8 is_set = 0;
16447   u8 is_en = 0;
16448   int ret;
16449
16450   /* Parse args required to build the message */
16451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16452     {
16453       if (unformat (input, "enable"))
16454         {
16455           is_set = 1;
16456           is_en = 1;
16457         }
16458       else if (unformat (input, "disable"))
16459         {
16460           is_set = 1;
16461         }
16462       else
16463         break;
16464     }
16465
16466   if (!is_set)
16467     {
16468       errmsg ("Value not set");
16469       return -99;
16470     }
16471
16472   M (ONE_STATS_ENABLE_DISABLE, mp);
16473   mp->is_en = is_en;
16474
16475   /* send */
16476   S (mp);
16477
16478   /* wait for reply */
16479   W (ret);
16480   return ret;
16481 }
16482
16483 static int
16484 api_show_one_stats_enable_disable (vat_main_t * vam)
16485 {
16486   vl_api_show_one_stats_enable_disable_t *mp;
16487   int ret;
16488
16489   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16490
16491   /* send */
16492   S (mp);
16493
16494   /* wait for reply */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 static int
16500 api_show_one_map_request_mode (vat_main_t * vam)
16501 {
16502   vl_api_show_one_map_request_mode_t *mp;
16503   int ret;
16504
16505   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16506
16507   /* send */
16508   S (mp);
16509
16510   /* wait for reply */
16511   W (ret);
16512   return ret;
16513 }
16514
16515 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16516
16517 static int
16518 api_one_map_request_mode (vat_main_t * vam)
16519 {
16520   unformat_input_t *input = vam->input;
16521   vl_api_one_map_request_mode_t *mp;
16522   u8 mode = 0;
16523   int ret;
16524
16525   /* Parse args required to build the message */
16526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16527     {
16528       if (unformat (input, "dst-only"))
16529         mode = 0;
16530       else if (unformat (input, "src-dst"))
16531         mode = 1;
16532       else
16533         {
16534           errmsg ("parse error '%U'", format_unformat_error, input);
16535           return -99;
16536         }
16537     }
16538
16539   M (ONE_MAP_REQUEST_MODE, mp);
16540
16541   mp->mode = mode;
16542
16543   /* send */
16544   S (mp);
16545
16546   /* wait for reply */
16547   W (ret);
16548   return ret;
16549 }
16550
16551 #define api_lisp_map_request_mode api_one_map_request_mode
16552
16553 /**
16554  * Enable/disable ONE proxy ITR.
16555  *
16556  * @param vam vpp API test context
16557  * @return return code
16558  */
16559 static int
16560 api_one_pitr_set_locator_set (vat_main_t * vam)
16561 {
16562   u8 ls_name_set = 0;
16563   unformat_input_t *input = vam->input;
16564   vl_api_one_pitr_set_locator_set_t *mp;
16565   u8 is_add = 1;
16566   u8 *ls_name = 0;
16567   int ret;
16568
16569   /* Parse args required to build the message */
16570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16571     {
16572       if (unformat (input, "del"))
16573         is_add = 0;
16574       else if (unformat (input, "locator-set %s", &ls_name))
16575         ls_name_set = 1;
16576       else
16577         {
16578           errmsg ("parse error '%U'", format_unformat_error, input);
16579           return -99;
16580         }
16581     }
16582
16583   if (!ls_name_set)
16584     {
16585       errmsg ("locator-set name not set!");
16586       return -99;
16587     }
16588
16589   M (ONE_PITR_SET_LOCATOR_SET, mp);
16590
16591   mp->is_add = is_add;
16592   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16593   vec_free (ls_name);
16594
16595   /* send */
16596   S (mp);
16597
16598   /* wait for reply */
16599   W (ret);
16600   return ret;
16601 }
16602
16603 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16604
16605 static int
16606 api_one_nsh_set_locator_set (vat_main_t * vam)
16607 {
16608   u8 ls_name_set = 0;
16609   unformat_input_t *input = vam->input;
16610   vl_api_one_nsh_set_locator_set_t *mp;
16611   u8 is_add = 1;
16612   u8 *ls_name = 0;
16613   int ret;
16614
16615   /* Parse args required to build the message */
16616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16617     {
16618       if (unformat (input, "del"))
16619         is_add = 0;
16620       else if (unformat (input, "ls %s", &ls_name))
16621         ls_name_set = 1;
16622       else
16623         {
16624           errmsg ("parse error '%U'", format_unformat_error, input);
16625           return -99;
16626         }
16627     }
16628
16629   if (!ls_name_set && is_add)
16630     {
16631       errmsg ("locator-set name not set!");
16632       return -99;
16633     }
16634
16635   M (ONE_NSH_SET_LOCATOR_SET, mp);
16636
16637   mp->is_add = is_add;
16638   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16639   vec_free (ls_name);
16640
16641   /* send */
16642   S (mp);
16643
16644   /* wait for reply */
16645   W (ret);
16646   return ret;
16647 }
16648
16649 static int
16650 api_show_one_pitr (vat_main_t * vam)
16651 {
16652   vl_api_show_one_pitr_t *mp;
16653   int ret;
16654
16655   if (!vam->json_output)
16656     {
16657       print (vam->ofp, "%=20s", "lisp status:");
16658     }
16659
16660   M (SHOW_ONE_PITR, mp);
16661   /* send it... */
16662   S (mp);
16663
16664   /* Wait for a reply... */
16665   W (ret);
16666   return ret;
16667 }
16668
16669 #define api_show_lisp_pitr api_show_one_pitr
16670
16671 static int
16672 api_one_use_petr (vat_main_t * vam)
16673 {
16674   unformat_input_t *input = vam->input;
16675   vl_api_one_use_petr_t *mp;
16676   u8 is_add = 0;
16677   ip_address_t ip;
16678   int ret;
16679
16680   clib_memset (&ip, 0, sizeof (ip));
16681
16682   /* Parse args required to build the message */
16683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16684     {
16685       if (unformat (input, "disable"))
16686         is_add = 0;
16687       else
16688         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16689         {
16690           is_add = 1;
16691           ip_addr_version (&ip) = IP4;
16692         }
16693       else
16694         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16695         {
16696           is_add = 1;
16697           ip_addr_version (&ip) = IP6;
16698         }
16699       else
16700         {
16701           errmsg ("parse error '%U'", format_unformat_error, input);
16702           return -99;
16703         }
16704     }
16705
16706   M (ONE_USE_PETR, mp);
16707
16708   mp->is_add = is_add;
16709   if (is_add)
16710     {
16711       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16712       if (mp->is_ip4)
16713         clib_memcpy (mp->address, &ip, 4);
16714       else
16715         clib_memcpy (mp->address, &ip, 16);
16716     }
16717
16718   /* send */
16719   S (mp);
16720
16721   /* wait for reply */
16722   W (ret);
16723   return ret;
16724 }
16725
16726 #define api_lisp_use_petr api_one_use_petr
16727
16728 static int
16729 api_show_one_nsh_mapping (vat_main_t * vam)
16730 {
16731   vl_api_show_one_use_petr_t *mp;
16732   int ret;
16733
16734   if (!vam->json_output)
16735     {
16736       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16737     }
16738
16739   M (SHOW_ONE_NSH_MAPPING, mp);
16740   /* send it... */
16741   S (mp);
16742
16743   /* Wait for a reply... */
16744   W (ret);
16745   return ret;
16746 }
16747
16748 static int
16749 api_show_one_use_petr (vat_main_t * vam)
16750 {
16751   vl_api_show_one_use_petr_t *mp;
16752   int ret;
16753
16754   if (!vam->json_output)
16755     {
16756       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16757     }
16758
16759   M (SHOW_ONE_USE_PETR, mp);
16760   /* send it... */
16761   S (mp);
16762
16763   /* Wait for a reply... */
16764   W (ret);
16765   return ret;
16766 }
16767
16768 #define api_show_lisp_use_petr api_show_one_use_petr
16769
16770 /**
16771  * Add/delete mapping between vni and vrf
16772  */
16773 static int
16774 api_one_eid_table_add_del_map (vat_main_t * vam)
16775 {
16776   unformat_input_t *input = vam->input;
16777   vl_api_one_eid_table_add_del_map_t *mp;
16778   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16779   u32 vni, vrf, bd_index;
16780   int ret;
16781
16782   /* Parse args required to build the message */
16783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16784     {
16785       if (unformat (input, "del"))
16786         is_add = 0;
16787       else if (unformat (input, "vrf %d", &vrf))
16788         vrf_set = 1;
16789       else if (unformat (input, "bd_index %d", &bd_index))
16790         bd_index_set = 1;
16791       else if (unformat (input, "vni %d", &vni))
16792         vni_set = 1;
16793       else
16794         break;
16795     }
16796
16797   if (!vni_set || (!vrf_set && !bd_index_set))
16798     {
16799       errmsg ("missing arguments!");
16800       return -99;
16801     }
16802
16803   if (vrf_set && bd_index_set)
16804     {
16805       errmsg ("error: both vrf and bd entered!");
16806       return -99;
16807     }
16808
16809   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16810
16811   mp->is_add = is_add;
16812   mp->vni = htonl (vni);
16813   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16814   mp->is_l2 = bd_index_set;
16815
16816   /* send */
16817   S (mp);
16818
16819   /* wait for reply */
16820   W (ret);
16821   return ret;
16822 }
16823
16824 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16825
16826 uword
16827 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16828 {
16829   u32 *action = va_arg (*args, u32 *);
16830   u8 *s = 0;
16831
16832   if (unformat (input, "%s", &s))
16833     {
16834       if (!strcmp ((char *) s, "no-action"))
16835         action[0] = 0;
16836       else if (!strcmp ((char *) s, "natively-forward"))
16837         action[0] = 1;
16838       else if (!strcmp ((char *) s, "send-map-request"))
16839         action[0] = 2;
16840       else if (!strcmp ((char *) s, "drop"))
16841         action[0] = 3;
16842       else
16843         {
16844           clib_warning ("invalid action: '%s'", s);
16845           action[0] = 3;
16846         }
16847     }
16848   else
16849     return 0;
16850
16851   vec_free (s);
16852   return 1;
16853 }
16854
16855 /**
16856  * Add/del remote mapping to/from ONE control plane
16857  *
16858  * @param vam vpp API test context
16859  * @return return code
16860  */
16861 static int
16862 api_one_add_del_remote_mapping (vat_main_t * vam)
16863 {
16864   unformat_input_t *input = vam->input;
16865   vl_api_one_add_del_remote_mapping_t *mp;
16866   u32 vni = 0;
16867   lisp_eid_vat_t _eid, *eid = &_eid;
16868   lisp_eid_vat_t _seid, *seid = &_seid;
16869   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16870   u32 action = ~0, p, w, data_len;
16871   ip4_address_t rloc4;
16872   ip6_address_t rloc6;
16873   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16874   int ret;
16875
16876   clib_memset (&rloc, 0, sizeof (rloc));
16877
16878   /* Parse args required to build the message */
16879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16880     {
16881       if (unformat (input, "del-all"))
16882         {
16883           del_all = 1;
16884         }
16885       else if (unformat (input, "del"))
16886         {
16887           is_add = 0;
16888         }
16889       else if (unformat (input, "add"))
16890         {
16891           is_add = 1;
16892         }
16893       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16894         {
16895           eid_set = 1;
16896         }
16897       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16898         {
16899           seid_set = 1;
16900         }
16901       else if (unformat (input, "vni %d", &vni))
16902         {
16903           ;
16904         }
16905       else if (unformat (input, "p %d w %d", &p, &w))
16906         {
16907           if (!curr_rloc)
16908             {
16909               errmsg ("No RLOC configured for setting priority/weight!");
16910               return -99;
16911             }
16912           curr_rloc->priority = p;
16913           curr_rloc->weight = w;
16914         }
16915       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16916         {
16917           rloc.is_ip4 = 1;
16918           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16919           vec_add1 (rlocs, rloc);
16920           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16921         }
16922       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16923         {
16924           rloc.is_ip4 = 0;
16925           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16926           vec_add1 (rlocs, rloc);
16927           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16928         }
16929       else if (unformat (input, "action %U",
16930                          unformat_negative_mapping_action, &action))
16931         {
16932           ;
16933         }
16934       else
16935         {
16936           clib_warning ("parse error '%U'", format_unformat_error, input);
16937           return -99;
16938         }
16939     }
16940
16941   if (0 == eid_set)
16942     {
16943       errmsg ("missing params!");
16944       return -99;
16945     }
16946
16947   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16948     {
16949       errmsg ("no action set for negative map-reply!");
16950       return -99;
16951     }
16952
16953   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16954
16955   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16956   mp->is_add = is_add;
16957   mp->vni = htonl (vni);
16958   mp->action = (u8) action;
16959   mp->is_src_dst = seid_set;
16960   mp->eid_len = eid->len;
16961   mp->seid_len = seid->len;
16962   mp->del_all = del_all;
16963   mp->eid_type = eid->type;
16964   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16965   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16966
16967   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16968   clib_memcpy (mp->rlocs, rlocs, data_len);
16969   vec_free (rlocs);
16970
16971   /* send it... */
16972   S (mp);
16973
16974   /* Wait for a reply... */
16975   W (ret);
16976   return ret;
16977 }
16978
16979 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16980
16981 /**
16982  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16983  * forwarding entries in data-plane accordingly.
16984  *
16985  * @param vam vpp API test context
16986  * @return return code
16987  */
16988 static int
16989 api_one_add_del_adjacency (vat_main_t * vam)
16990 {
16991   unformat_input_t *input = vam->input;
16992   vl_api_one_add_del_adjacency_t *mp;
16993   u32 vni = 0;
16994   ip4_address_t leid4, reid4;
16995   ip6_address_t leid6, reid6;
16996   u8 reid_mac[6] = { 0 };
16997   u8 leid_mac[6] = { 0 };
16998   u8 reid_type, leid_type;
16999   u32 leid_len = 0, reid_len = 0, len;
17000   u8 is_add = 1;
17001   int ret;
17002
17003   leid_type = reid_type = (u8) ~ 0;
17004
17005   /* Parse args required to build the message */
17006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17007     {
17008       if (unformat (input, "del"))
17009         {
17010           is_add = 0;
17011         }
17012       else if (unformat (input, "add"))
17013         {
17014           is_add = 1;
17015         }
17016       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17017                          &reid4, &len))
17018         {
17019           reid_type = 0;        /* ipv4 */
17020           reid_len = len;
17021         }
17022       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17023                          &reid6, &len))
17024         {
17025           reid_type = 1;        /* ipv6 */
17026           reid_len = len;
17027         }
17028       else if (unformat (input, "reid %U", unformat_ethernet_address,
17029                          reid_mac))
17030         {
17031           reid_type = 2;        /* mac */
17032         }
17033       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17034                          &leid4, &len))
17035         {
17036           leid_type = 0;        /* ipv4 */
17037           leid_len = len;
17038         }
17039       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17040                          &leid6, &len))
17041         {
17042           leid_type = 1;        /* ipv6 */
17043           leid_len = len;
17044         }
17045       else if (unformat (input, "leid %U", unformat_ethernet_address,
17046                          leid_mac))
17047         {
17048           leid_type = 2;        /* mac */
17049         }
17050       else if (unformat (input, "vni %d", &vni))
17051         {
17052           ;
17053         }
17054       else
17055         {
17056           errmsg ("parse error '%U'", format_unformat_error, input);
17057           return -99;
17058         }
17059     }
17060
17061   if ((u8) ~ 0 == reid_type)
17062     {
17063       errmsg ("missing params!");
17064       return -99;
17065     }
17066
17067   if (leid_type != reid_type)
17068     {
17069       errmsg ("remote and local EIDs are of different types!");
17070       return -99;
17071     }
17072
17073   M (ONE_ADD_DEL_ADJACENCY, mp);
17074   mp->is_add = is_add;
17075   mp->vni = htonl (vni);
17076   mp->leid_len = leid_len;
17077   mp->reid_len = reid_len;
17078   mp->eid_type = reid_type;
17079
17080   switch (mp->eid_type)
17081     {
17082     case 0:
17083       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17084       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17085       break;
17086     case 1:
17087       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17088       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17089       break;
17090     case 2:
17091       clib_memcpy (mp->leid, leid_mac, 6);
17092       clib_memcpy (mp->reid, reid_mac, 6);
17093       break;
17094     default:
17095       errmsg ("unknown EID type %d!", mp->eid_type);
17096       return 0;
17097     }
17098
17099   /* send it... */
17100   S (mp);
17101
17102   /* Wait for a reply... */
17103   W (ret);
17104   return ret;
17105 }
17106
17107 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17108
17109 uword
17110 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17111 {
17112   u32 *mode = va_arg (*args, u32 *);
17113
17114   if (unformat (input, "lisp"))
17115     *mode = 0;
17116   else if (unformat (input, "vxlan"))
17117     *mode = 1;
17118   else
17119     return 0;
17120
17121   return 1;
17122 }
17123
17124 static int
17125 api_gpe_get_encap_mode (vat_main_t * vam)
17126 {
17127   vl_api_gpe_get_encap_mode_t *mp;
17128   int ret;
17129
17130   /* Construct the API message */
17131   M (GPE_GET_ENCAP_MODE, mp);
17132
17133   /* send it... */
17134   S (mp);
17135
17136   /* Wait for a reply... */
17137   W (ret);
17138   return ret;
17139 }
17140
17141 static int
17142 api_gpe_set_encap_mode (vat_main_t * vam)
17143 {
17144   unformat_input_t *input = vam->input;
17145   vl_api_gpe_set_encap_mode_t *mp;
17146   int ret;
17147   u32 mode = 0;
17148
17149   /* Parse args required to build the message */
17150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17151     {
17152       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17153         ;
17154       else
17155         break;
17156     }
17157
17158   /* Construct the API message */
17159   M (GPE_SET_ENCAP_MODE, mp);
17160
17161   mp->mode = mode;
17162
17163   /* send it... */
17164   S (mp);
17165
17166   /* Wait for a reply... */
17167   W (ret);
17168   return ret;
17169 }
17170
17171 static int
17172 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17173 {
17174   unformat_input_t *input = vam->input;
17175   vl_api_gpe_add_del_iface_t *mp;
17176   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17177   u32 dp_table = 0, vni = 0;
17178   int ret;
17179
17180   /* Parse args required to build the message */
17181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17182     {
17183       if (unformat (input, "up"))
17184         {
17185           action_set = 1;
17186           is_add = 1;
17187         }
17188       else if (unformat (input, "down"))
17189         {
17190           action_set = 1;
17191           is_add = 0;
17192         }
17193       else if (unformat (input, "table_id %d", &dp_table))
17194         {
17195           dp_table_set = 1;
17196         }
17197       else if (unformat (input, "bd_id %d", &dp_table))
17198         {
17199           dp_table_set = 1;
17200           is_l2 = 1;
17201         }
17202       else if (unformat (input, "vni %d", &vni))
17203         {
17204           vni_set = 1;
17205         }
17206       else
17207         break;
17208     }
17209
17210   if (action_set == 0)
17211     {
17212       errmsg ("Action not set");
17213       return -99;
17214     }
17215   if (dp_table_set == 0 || vni_set == 0)
17216     {
17217       errmsg ("vni and dp_table must be set");
17218       return -99;
17219     }
17220
17221   /* Construct the API message */
17222   M (GPE_ADD_DEL_IFACE, mp);
17223
17224   mp->is_add = is_add;
17225   mp->dp_table = clib_host_to_net_u32 (dp_table);
17226   mp->is_l2 = is_l2;
17227   mp->vni = clib_host_to_net_u32 (vni);
17228
17229   /* send it... */
17230   S (mp);
17231
17232   /* Wait for a reply... */
17233   W (ret);
17234   return ret;
17235 }
17236
17237 static int
17238 api_one_map_register_fallback_threshold (vat_main_t * vam)
17239 {
17240   unformat_input_t *input = vam->input;
17241   vl_api_one_map_register_fallback_threshold_t *mp;
17242   u32 value = 0;
17243   u8 is_set = 0;
17244   int ret;
17245
17246   /* Parse args required to build the message */
17247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17248     {
17249       if (unformat (input, "%u", &value))
17250         is_set = 1;
17251       else
17252         {
17253           clib_warning ("parse error '%U'", format_unformat_error, input);
17254           return -99;
17255         }
17256     }
17257
17258   if (!is_set)
17259     {
17260       errmsg ("fallback threshold value is missing!");
17261       return -99;
17262     }
17263
17264   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17265   mp->value = clib_host_to_net_u32 (value);
17266
17267   /* send it... */
17268   S (mp);
17269
17270   /* Wait for a reply... */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 static int
17276 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17277 {
17278   vl_api_show_one_map_register_fallback_threshold_t *mp;
17279   int ret;
17280
17281   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17282
17283   /* send it... */
17284   S (mp);
17285
17286   /* Wait for a reply... */
17287   W (ret);
17288   return ret;
17289 }
17290
17291 uword
17292 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17293 {
17294   u32 *proto = va_arg (*args, u32 *);
17295
17296   if (unformat (input, "udp"))
17297     *proto = 1;
17298   else if (unformat (input, "api"))
17299     *proto = 2;
17300   else
17301     return 0;
17302
17303   return 1;
17304 }
17305
17306 static int
17307 api_one_set_transport_protocol (vat_main_t * vam)
17308 {
17309   unformat_input_t *input = vam->input;
17310   vl_api_one_set_transport_protocol_t *mp;
17311   u8 is_set = 0;
17312   u32 protocol = 0;
17313   int ret;
17314
17315   /* Parse args required to build the message */
17316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17317     {
17318       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17319         is_set = 1;
17320       else
17321         {
17322           clib_warning ("parse error '%U'", format_unformat_error, input);
17323           return -99;
17324         }
17325     }
17326
17327   if (!is_set)
17328     {
17329       errmsg ("Transport protocol missing!");
17330       return -99;
17331     }
17332
17333   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17334   mp->protocol = (u8) protocol;
17335
17336   /* send it... */
17337   S (mp);
17338
17339   /* Wait for a reply... */
17340   W (ret);
17341   return ret;
17342 }
17343
17344 static int
17345 api_one_get_transport_protocol (vat_main_t * vam)
17346 {
17347   vl_api_one_get_transport_protocol_t *mp;
17348   int ret;
17349
17350   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17351
17352   /* send it... */
17353   S (mp);
17354
17355   /* Wait for a reply... */
17356   W (ret);
17357   return ret;
17358 }
17359
17360 static int
17361 api_one_map_register_set_ttl (vat_main_t * vam)
17362 {
17363   unformat_input_t *input = vam->input;
17364   vl_api_one_map_register_set_ttl_t *mp;
17365   u32 ttl = 0;
17366   u8 is_set = 0;
17367   int ret;
17368
17369   /* Parse args required to build the message */
17370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17371     {
17372       if (unformat (input, "%u", &ttl))
17373         is_set = 1;
17374       else
17375         {
17376           clib_warning ("parse error '%U'", format_unformat_error, input);
17377           return -99;
17378         }
17379     }
17380
17381   if (!is_set)
17382     {
17383       errmsg ("TTL value missing!");
17384       return -99;
17385     }
17386
17387   M (ONE_MAP_REGISTER_SET_TTL, mp);
17388   mp->ttl = clib_host_to_net_u32 (ttl);
17389
17390   /* send it... */
17391   S (mp);
17392
17393   /* Wait for a reply... */
17394   W (ret);
17395   return ret;
17396 }
17397
17398 static int
17399 api_show_one_map_register_ttl (vat_main_t * vam)
17400 {
17401   vl_api_show_one_map_register_ttl_t *mp;
17402   int ret;
17403
17404   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17405
17406   /* send it... */
17407   S (mp);
17408
17409   /* Wait for a reply... */
17410   W (ret);
17411   return ret;
17412 }
17413
17414 /**
17415  * Add/del map request itr rlocs from ONE control plane and updates
17416  *
17417  * @param vam vpp API test context
17418  * @return return code
17419  */
17420 static int
17421 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17422 {
17423   unformat_input_t *input = vam->input;
17424   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17425   u8 *locator_set_name = 0;
17426   u8 locator_set_name_set = 0;
17427   u8 is_add = 1;
17428   int ret;
17429
17430   /* Parse args required to build the message */
17431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17432     {
17433       if (unformat (input, "del"))
17434         {
17435           is_add = 0;
17436         }
17437       else if (unformat (input, "%_%v%_", &locator_set_name))
17438         {
17439           locator_set_name_set = 1;
17440         }
17441       else
17442         {
17443           clib_warning ("parse error '%U'", format_unformat_error, input);
17444           return -99;
17445         }
17446     }
17447
17448   if (is_add && !locator_set_name_set)
17449     {
17450       errmsg ("itr-rloc is not set!");
17451       return -99;
17452     }
17453
17454   if (is_add && vec_len (locator_set_name) > 64)
17455     {
17456       errmsg ("itr-rloc locator-set name too long");
17457       vec_free (locator_set_name);
17458       return -99;
17459     }
17460
17461   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17462   mp->is_add = is_add;
17463   if (is_add)
17464     {
17465       clib_memcpy (mp->locator_set_name, locator_set_name,
17466                    vec_len (locator_set_name));
17467     }
17468   else
17469     {
17470       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17471     }
17472   vec_free (locator_set_name);
17473
17474   /* send it... */
17475   S (mp);
17476
17477   /* Wait for a reply... */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17483
17484 static int
17485 api_one_locator_dump (vat_main_t * vam)
17486 {
17487   unformat_input_t *input = vam->input;
17488   vl_api_one_locator_dump_t *mp;
17489   vl_api_control_ping_t *mp_ping;
17490   u8 is_index_set = 0, is_name_set = 0;
17491   u8 *ls_name = 0;
17492   u32 ls_index = ~0;
17493   int ret;
17494
17495   /* Parse args required to build the message */
17496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17497     {
17498       if (unformat (input, "ls_name %_%v%_", &ls_name))
17499         {
17500           is_name_set = 1;
17501         }
17502       else if (unformat (input, "ls_index %d", &ls_index))
17503         {
17504           is_index_set = 1;
17505         }
17506       else
17507         {
17508           errmsg ("parse error '%U'", format_unformat_error, input);
17509           return -99;
17510         }
17511     }
17512
17513   if (!is_index_set && !is_name_set)
17514     {
17515       errmsg ("error: expected one of index or name!");
17516       return -99;
17517     }
17518
17519   if (is_index_set && is_name_set)
17520     {
17521       errmsg ("error: only one param expected!");
17522       return -99;
17523     }
17524
17525   if (vec_len (ls_name) > 62)
17526     {
17527       errmsg ("error: locator set name too long!");
17528       return -99;
17529     }
17530
17531   if (!vam->json_output)
17532     {
17533       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17534     }
17535
17536   M (ONE_LOCATOR_DUMP, mp);
17537   mp->is_index_set = is_index_set;
17538
17539   if (is_index_set)
17540     mp->ls_index = clib_host_to_net_u32 (ls_index);
17541   else
17542     {
17543       vec_add1 (ls_name, 0);
17544       strncpy ((char *) mp->ls_name, (char *) ls_name,
17545                sizeof (mp->ls_name) - 1);
17546     }
17547
17548   /* send it... */
17549   S (mp);
17550
17551   /* Use a control ping for synchronization */
17552   MPING (CONTROL_PING, mp_ping);
17553   S (mp_ping);
17554
17555   /* Wait for a reply... */
17556   W (ret);
17557   return ret;
17558 }
17559
17560 #define api_lisp_locator_dump api_one_locator_dump
17561
17562 static int
17563 api_one_locator_set_dump (vat_main_t * vam)
17564 {
17565   vl_api_one_locator_set_dump_t *mp;
17566   vl_api_control_ping_t *mp_ping;
17567   unformat_input_t *input = vam->input;
17568   u8 filter = 0;
17569   int ret;
17570
17571   /* Parse args required to build the message */
17572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17573     {
17574       if (unformat (input, "local"))
17575         {
17576           filter = 1;
17577         }
17578       else if (unformat (input, "remote"))
17579         {
17580           filter = 2;
17581         }
17582       else
17583         {
17584           errmsg ("parse error '%U'", format_unformat_error, input);
17585           return -99;
17586         }
17587     }
17588
17589   if (!vam->json_output)
17590     {
17591       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17592     }
17593
17594   M (ONE_LOCATOR_SET_DUMP, mp);
17595
17596   mp->filter = filter;
17597
17598   /* send it... */
17599   S (mp);
17600
17601   /* Use a control ping for synchronization */
17602   MPING (CONTROL_PING, mp_ping);
17603   S (mp_ping);
17604
17605   /* Wait for a reply... */
17606   W (ret);
17607   return ret;
17608 }
17609
17610 #define api_lisp_locator_set_dump api_one_locator_set_dump
17611
17612 static int
17613 api_one_eid_table_map_dump (vat_main_t * vam)
17614 {
17615   u8 is_l2 = 0;
17616   u8 mode_set = 0;
17617   unformat_input_t *input = vam->input;
17618   vl_api_one_eid_table_map_dump_t *mp;
17619   vl_api_control_ping_t *mp_ping;
17620   int ret;
17621
17622   /* Parse args required to build the message */
17623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17624     {
17625       if (unformat (input, "l2"))
17626         {
17627           is_l2 = 1;
17628           mode_set = 1;
17629         }
17630       else if (unformat (input, "l3"))
17631         {
17632           is_l2 = 0;
17633           mode_set = 1;
17634         }
17635       else
17636         {
17637           errmsg ("parse error '%U'", format_unformat_error, input);
17638           return -99;
17639         }
17640     }
17641
17642   if (!mode_set)
17643     {
17644       errmsg ("expected one of 'l2' or 'l3' parameter!");
17645       return -99;
17646     }
17647
17648   if (!vam->json_output)
17649     {
17650       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17651     }
17652
17653   M (ONE_EID_TABLE_MAP_DUMP, mp);
17654   mp->is_l2 = is_l2;
17655
17656   /* send it... */
17657   S (mp);
17658
17659   /* Use a control ping for synchronization */
17660   MPING (CONTROL_PING, mp_ping);
17661   S (mp_ping);
17662
17663   /* Wait for a reply... */
17664   W (ret);
17665   return ret;
17666 }
17667
17668 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17669
17670 static int
17671 api_one_eid_table_vni_dump (vat_main_t * vam)
17672 {
17673   vl_api_one_eid_table_vni_dump_t *mp;
17674   vl_api_control_ping_t *mp_ping;
17675   int ret;
17676
17677   if (!vam->json_output)
17678     {
17679       print (vam->ofp, "VNI");
17680     }
17681
17682   M (ONE_EID_TABLE_VNI_DUMP, mp);
17683
17684   /* send it... */
17685   S (mp);
17686
17687   /* Use a control ping for synchronization */
17688   MPING (CONTROL_PING, mp_ping);
17689   S (mp_ping);
17690
17691   /* Wait for a reply... */
17692   W (ret);
17693   return ret;
17694 }
17695
17696 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17697
17698 static int
17699 api_one_eid_table_dump (vat_main_t * vam)
17700 {
17701   unformat_input_t *i = vam->input;
17702   vl_api_one_eid_table_dump_t *mp;
17703   vl_api_control_ping_t *mp_ping;
17704   struct in_addr ip4;
17705   struct in6_addr ip6;
17706   u8 mac[6];
17707   u8 eid_type = ~0, eid_set = 0;
17708   u32 prefix_length = ~0, t, vni = 0;
17709   u8 filter = 0;
17710   int ret;
17711   lisp_nsh_api_t nsh;
17712
17713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17714     {
17715       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17716         {
17717           eid_set = 1;
17718           eid_type = 0;
17719           prefix_length = t;
17720         }
17721       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17722         {
17723           eid_set = 1;
17724           eid_type = 1;
17725           prefix_length = t;
17726         }
17727       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17728         {
17729           eid_set = 1;
17730           eid_type = 2;
17731         }
17732       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17733         {
17734           eid_set = 1;
17735           eid_type = 3;
17736         }
17737       else if (unformat (i, "vni %d", &t))
17738         {
17739           vni = t;
17740         }
17741       else if (unformat (i, "local"))
17742         {
17743           filter = 1;
17744         }
17745       else if (unformat (i, "remote"))
17746         {
17747           filter = 2;
17748         }
17749       else
17750         {
17751           errmsg ("parse error '%U'", format_unformat_error, i);
17752           return -99;
17753         }
17754     }
17755
17756   if (!vam->json_output)
17757     {
17758       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17759              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17760     }
17761
17762   M (ONE_EID_TABLE_DUMP, mp);
17763
17764   mp->filter = filter;
17765   if (eid_set)
17766     {
17767       mp->eid_set = 1;
17768       mp->vni = htonl (vni);
17769       mp->eid_type = eid_type;
17770       switch (eid_type)
17771         {
17772         case 0:
17773           mp->prefix_length = prefix_length;
17774           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17775           break;
17776         case 1:
17777           mp->prefix_length = prefix_length;
17778           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17779           break;
17780         case 2:
17781           clib_memcpy (mp->eid, mac, sizeof (mac));
17782           break;
17783         case 3:
17784           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17785           break;
17786         default:
17787           errmsg ("unknown EID type %d!", eid_type);
17788           return -99;
17789         }
17790     }
17791
17792   /* send it... */
17793   S (mp);
17794
17795   /* Use a control ping for synchronization */
17796   MPING (CONTROL_PING, mp_ping);
17797   S (mp_ping);
17798
17799   /* Wait for a reply... */
17800   W (ret);
17801   return ret;
17802 }
17803
17804 #define api_lisp_eid_table_dump api_one_eid_table_dump
17805
17806 static int
17807 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17808 {
17809   unformat_input_t *i = vam->input;
17810   vl_api_gpe_fwd_entries_get_t *mp;
17811   u8 vni_set = 0;
17812   u32 vni = ~0;
17813   int ret;
17814
17815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17816     {
17817       if (unformat (i, "vni %d", &vni))
17818         {
17819           vni_set = 1;
17820         }
17821       else
17822         {
17823           errmsg ("parse error '%U'", format_unformat_error, i);
17824           return -99;
17825         }
17826     }
17827
17828   if (!vni_set)
17829     {
17830       errmsg ("vni not set!");
17831       return -99;
17832     }
17833
17834   if (!vam->json_output)
17835     {
17836       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17837              "leid", "reid");
17838     }
17839
17840   M (GPE_FWD_ENTRIES_GET, mp);
17841   mp->vni = clib_host_to_net_u32 (vni);
17842
17843   /* send it... */
17844   S (mp);
17845
17846   /* Wait for a reply... */
17847   W (ret);
17848   return ret;
17849 }
17850
17851 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17852 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17853 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17854 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17855 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17856 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17857 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17858 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17859
17860 static int
17861 api_one_adjacencies_get (vat_main_t * vam)
17862 {
17863   unformat_input_t *i = vam->input;
17864   vl_api_one_adjacencies_get_t *mp;
17865   u8 vni_set = 0;
17866   u32 vni = ~0;
17867   int ret;
17868
17869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17870     {
17871       if (unformat (i, "vni %d", &vni))
17872         {
17873           vni_set = 1;
17874         }
17875       else
17876         {
17877           errmsg ("parse error '%U'", format_unformat_error, i);
17878           return -99;
17879         }
17880     }
17881
17882   if (!vni_set)
17883     {
17884       errmsg ("vni not set!");
17885       return -99;
17886     }
17887
17888   if (!vam->json_output)
17889     {
17890       print (vam->ofp, "%s %40s", "leid", "reid");
17891     }
17892
17893   M (ONE_ADJACENCIES_GET, mp);
17894   mp->vni = clib_host_to_net_u32 (vni);
17895
17896   /* send it... */
17897   S (mp);
17898
17899   /* Wait for a reply... */
17900   W (ret);
17901   return ret;
17902 }
17903
17904 #define api_lisp_adjacencies_get api_one_adjacencies_get
17905
17906 static int
17907 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17908 {
17909   unformat_input_t *i = vam->input;
17910   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17911   int ret;
17912   u8 ip_family_set = 0, is_ip4 = 1;
17913
17914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17915     {
17916       if (unformat (i, "ip4"))
17917         {
17918           ip_family_set = 1;
17919           is_ip4 = 1;
17920         }
17921       else if (unformat (i, "ip6"))
17922         {
17923           ip_family_set = 1;
17924           is_ip4 = 0;
17925         }
17926       else
17927         {
17928           errmsg ("parse error '%U'", format_unformat_error, i);
17929           return -99;
17930         }
17931     }
17932
17933   if (!ip_family_set)
17934     {
17935       errmsg ("ip family not set!");
17936       return -99;
17937     }
17938
17939   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17940   mp->is_ip4 = is_ip4;
17941
17942   /* send it... */
17943   S (mp);
17944
17945   /* Wait for a reply... */
17946   W (ret);
17947   return ret;
17948 }
17949
17950 static int
17951 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17952 {
17953   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17954   int ret;
17955
17956   if (!vam->json_output)
17957     {
17958       print (vam->ofp, "VNIs");
17959     }
17960
17961   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17962
17963   /* send it... */
17964   S (mp);
17965
17966   /* Wait for a reply... */
17967   W (ret);
17968   return ret;
17969 }
17970
17971 static int
17972 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17973 {
17974   unformat_input_t *i = vam->input;
17975   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17976   int ret = 0;
17977   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17978   struct in_addr ip4;
17979   struct in6_addr ip6;
17980   u32 table_id = 0, nh_sw_if_index = ~0;
17981
17982   clib_memset (&ip4, 0, sizeof (ip4));
17983   clib_memset (&ip6, 0, sizeof (ip6));
17984
17985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17986     {
17987       if (unformat (i, "del"))
17988         is_add = 0;
17989       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17990                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17991         {
17992           ip_set = 1;
17993           is_ip4 = 1;
17994         }
17995       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17996                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17997         {
17998           ip_set = 1;
17999           is_ip4 = 0;
18000         }
18001       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18002         {
18003           ip_set = 1;
18004           is_ip4 = 1;
18005           nh_sw_if_index = ~0;
18006         }
18007       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18008         {
18009           ip_set = 1;
18010           is_ip4 = 0;
18011           nh_sw_if_index = ~0;
18012         }
18013       else if (unformat (i, "table %d", &table_id))
18014         ;
18015       else
18016         {
18017           errmsg ("parse error '%U'", format_unformat_error, i);
18018           return -99;
18019         }
18020     }
18021
18022   if (!ip_set)
18023     {
18024       errmsg ("nh addr not set!");
18025       return -99;
18026     }
18027
18028   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18029   mp->is_add = is_add;
18030   mp->table_id = clib_host_to_net_u32 (table_id);
18031   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18032   mp->is_ip4 = is_ip4;
18033   if (is_ip4)
18034     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18035   else
18036     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18037
18038   /* send it... */
18039   S (mp);
18040
18041   /* Wait for a reply... */
18042   W (ret);
18043   return ret;
18044 }
18045
18046 static int
18047 api_one_map_server_dump (vat_main_t * vam)
18048 {
18049   vl_api_one_map_server_dump_t *mp;
18050   vl_api_control_ping_t *mp_ping;
18051   int ret;
18052
18053   if (!vam->json_output)
18054     {
18055       print (vam->ofp, "%=20s", "Map server");
18056     }
18057
18058   M (ONE_MAP_SERVER_DUMP, mp);
18059   /* send it... */
18060   S (mp);
18061
18062   /* Use a control ping for synchronization */
18063   MPING (CONTROL_PING, mp_ping);
18064   S (mp_ping);
18065
18066   /* Wait for a reply... */
18067   W (ret);
18068   return ret;
18069 }
18070
18071 #define api_lisp_map_server_dump api_one_map_server_dump
18072
18073 static int
18074 api_one_map_resolver_dump (vat_main_t * vam)
18075 {
18076   vl_api_one_map_resolver_dump_t *mp;
18077   vl_api_control_ping_t *mp_ping;
18078   int ret;
18079
18080   if (!vam->json_output)
18081     {
18082       print (vam->ofp, "%=20s", "Map resolver");
18083     }
18084
18085   M (ONE_MAP_RESOLVER_DUMP, mp);
18086   /* send it... */
18087   S (mp);
18088
18089   /* Use a control ping for synchronization */
18090   MPING (CONTROL_PING, mp_ping);
18091   S (mp_ping);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18099
18100 static int
18101 api_one_stats_flush (vat_main_t * vam)
18102 {
18103   vl_api_one_stats_flush_t *mp;
18104   int ret = 0;
18105
18106   M (ONE_STATS_FLUSH, mp);
18107   S (mp);
18108   W (ret);
18109   return ret;
18110 }
18111
18112 static int
18113 api_one_stats_dump (vat_main_t * vam)
18114 {
18115   vl_api_one_stats_dump_t *mp;
18116   vl_api_control_ping_t *mp_ping;
18117   int ret;
18118
18119   M (ONE_STATS_DUMP, mp);
18120   /* send it... */
18121   S (mp);
18122
18123   /* Use a control ping for synchronization */
18124   MPING (CONTROL_PING, mp_ping);
18125   S (mp_ping);
18126
18127   /* Wait for a reply... */
18128   W (ret);
18129   return ret;
18130 }
18131
18132 static int
18133 api_show_one_status (vat_main_t * vam)
18134 {
18135   vl_api_show_one_status_t *mp;
18136   int ret;
18137
18138   if (!vam->json_output)
18139     {
18140       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18141     }
18142
18143   M (SHOW_ONE_STATUS, mp);
18144   /* send it... */
18145   S (mp);
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_show_lisp_status api_show_one_status
18152
18153 static int
18154 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18155 {
18156   vl_api_gpe_fwd_entry_path_dump_t *mp;
18157   vl_api_control_ping_t *mp_ping;
18158   unformat_input_t *i = vam->input;
18159   u32 fwd_entry_index = ~0;
18160   int ret;
18161
18162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18163     {
18164       if (unformat (i, "index %d", &fwd_entry_index))
18165         ;
18166       else
18167         break;
18168     }
18169
18170   if (~0 == fwd_entry_index)
18171     {
18172       errmsg ("no index specified!");
18173       return -99;
18174     }
18175
18176   if (!vam->json_output)
18177     {
18178       print (vam->ofp, "first line");
18179     }
18180
18181   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18182
18183   /* send it... */
18184   S (mp);
18185   /* Use a control ping for synchronization */
18186   MPING (CONTROL_PING, mp_ping);
18187   S (mp_ping);
18188
18189   /* Wait for a reply... */
18190   W (ret);
18191   return ret;
18192 }
18193
18194 static int
18195 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18196 {
18197   vl_api_one_get_map_request_itr_rlocs_t *mp;
18198   int ret;
18199
18200   if (!vam->json_output)
18201     {
18202       print (vam->ofp, "%=20s", "itr-rlocs:");
18203     }
18204
18205   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18206   /* send it... */
18207   S (mp);
18208   /* Wait for a reply... */
18209   W (ret);
18210   return ret;
18211 }
18212
18213 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18214
18215 static int
18216 api_af_packet_create (vat_main_t * vam)
18217 {
18218   unformat_input_t *i = vam->input;
18219   vl_api_af_packet_create_t *mp;
18220   u8 *host_if_name = 0;
18221   u8 hw_addr[6];
18222   u8 random_hw_addr = 1;
18223   int ret;
18224
18225   clib_memset (hw_addr, 0, sizeof (hw_addr));
18226
18227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18228     {
18229       if (unformat (i, "name %s", &host_if_name))
18230         vec_add1 (host_if_name, 0);
18231       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18232         random_hw_addr = 0;
18233       else
18234         break;
18235     }
18236
18237   if (!vec_len (host_if_name))
18238     {
18239       errmsg ("host-interface name must be specified");
18240       return -99;
18241     }
18242
18243   if (vec_len (host_if_name) > 64)
18244     {
18245       errmsg ("host-interface name too long");
18246       return -99;
18247     }
18248
18249   M (AF_PACKET_CREATE, mp);
18250
18251   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18252   clib_memcpy (mp->hw_addr, hw_addr, 6);
18253   mp->use_random_hw_addr = random_hw_addr;
18254   vec_free (host_if_name);
18255
18256   S (mp);
18257
18258   /* *INDENT-OFF* */
18259   W2 (ret,
18260       ({
18261         if (ret == 0)
18262           fprintf (vam->ofp ? vam->ofp : stderr,
18263                    " new sw_if_index = %d\n", vam->sw_if_index);
18264       }));
18265   /* *INDENT-ON* */
18266   return ret;
18267 }
18268
18269 static int
18270 api_af_packet_delete (vat_main_t * vam)
18271 {
18272   unformat_input_t *i = vam->input;
18273   vl_api_af_packet_delete_t *mp;
18274   u8 *host_if_name = 0;
18275   int ret;
18276
18277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18278     {
18279       if (unformat (i, "name %s", &host_if_name))
18280         vec_add1 (host_if_name, 0);
18281       else
18282         break;
18283     }
18284
18285   if (!vec_len (host_if_name))
18286     {
18287       errmsg ("host-interface name must be specified");
18288       return -99;
18289     }
18290
18291   if (vec_len (host_if_name) > 64)
18292     {
18293       errmsg ("host-interface name too long");
18294       return -99;
18295     }
18296
18297   M (AF_PACKET_DELETE, mp);
18298
18299   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18300   vec_free (host_if_name);
18301
18302   S (mp);
18303   W (ret);
18304   return ret;
18305 }
18306
18307 static void vl_api_af_packet_details_t_handler
18308   (vl_api_af_packet_details_t * mp)
18309 {
18310   vat_main_t *vam = &vat_main;
18311
18312   print (vam->ofp, "%-16s %d",
18313          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18314 }
18315
18316 static void vl_api_af_packet_details_t_handler_json
18317   (vl_api_af_packet_details_t * mp)
18318 {
18319   vat_main_t *vam = &vat_main;
18320   vat_json_node_t *node = NULL;
18321
18322   if (VAT_JSON_ARRAY != vam->json_tree.type)
18323     {
18324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18325       vat_json_init_array (&vam->json_tree);
18326     }
18327   node = vat_json_array_add (&vam->json_tree);
18328
18329   vat_json_init_object (node);
18330   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18331   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18332 }
18333
18334 static int
18335 api_af_packet_dump (vat_main_t * vam)
18336 {
18337   vl_api_af_packet_dump_t *mp;
18338   vl_api_control_ping_t *mp_ping;
18339   int ret;
18340
18341   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18342   /* Get list of tap interfaces */
18343   M (AF_PACKET_DUMP, mp);
18344   S (mp);
18345
18346   /* Use a control ping for synchronization */
18347   MPING (CONTROL_PING, mp_ping);
18348   S (mp_ping);
18349
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_policer_add_del (vat_main_t * vam)
18356 {
18357   unformat_input_t *i = vam->input;
18358   vl_api_policer_add_del_t *mp;
18359   u8 is_add = 1;
18360   u8 *name = 0;
18361   u32 cir = 0;
18362   u32 eir = 0;
18363   u64 cb = 0;
18364   u64 eb = 0;
18365   u8 rate_type = 0;
18366   u8 round_type = 0;
18367   u8 type = 0;
18368   u8 color_aware = 0;
18369   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18370   int ret;
18371
18372   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18373   conform_action.dscp = 0;
18374   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18375   exceed_action.dscp = 0;
18376   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18377   violate_action.dscp = 0;
18378
18379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18380     {
18381       if (unformat (i, "del"))
18382         is_add = 0;
18383       else if (unformat (i, "name %s", &name))
18384         vec_add1 (name, 0);
18385       else if (unformat (i, "cir %u", &cir))
18386         ;
18387       else if (unformat (i, "eir %u", &eir))
18388         ;
18389       else if (unformat (i, "cb %u", &cb))
18390         ;
18391       else if (unformat (i, "eb %u", &eb))
18392         ;
18393       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18394                          &rate_type))
18395         ;
18396       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18397                          &round_type))
18398         ;
18399       else if (unformat (i, "type %U", unformat_policer_type, &type))
18400         ;
18401       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18402                          &conform_action))
18403         ;
18404       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18405                          &exceed_action))
18406         ;
18407       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18408                          &violate_action))
18409         ;
18410       else if (unformat (i, "color-aware"))
18411         color_aware = 1;
18412       else
18413         break;
18414     }
18415
18416   if (!vec_len (name))
18417     {
18418       errmsg ("policer name must be specified");
18419       return -99;
18420     }
18421
18422   if (vec_len (name) > 64)
18423     {
18424       errmsg ("policer name too long");
18425       return -99;
18426     }
18427
18428   M (POLICER_ADD_DEL, mp);
18429
18430   clib_memcpy (mp->name, name, vec_len (name));
18431   vec_free (name);
18432   mp->is_add = is_add;
18433   mp->cir = ntohl (cir);
18434   mp->eir = ntohl (eir);
18435   mp->cb = clib_net_to_host_u64 (cb);
18436   mp->eb = clib_net_to_host_u64 (eb);
18437   mp->rate_type = rate_type;
18438   mp->round_type = round_type;
18439   mp->type = type;
18440   mp->conform_action_type = conform_action.action_type;
18441   mp->conform_dscp = conform_action.dscp;
18442   mp->exceed_action_type = exceed_action.action_type;
18443   mp->exceed_dscp = exceed_action.dscp;
18444   mp->violate_action_type = violate_action.action_type;
18445   mp->violate_dscp = violate_action.dscp;
18446   mp->color_aware = color_aware;
18447
18448   S (mp);
18449   W (ret);
18450   return ret;
18451 }
18452
18453 static int
18454 api_policer_dump (vat_main_t * vam)
18455 {
18456   unformat_input_t *i = vam->input;
18457   vl_api_policer_dump_t *mp;
18458   vl_api_control_ping_t *mp_ping;
18459   u8 *match_name = 0;
18460   u8 match_name_valid = 0;
18461   int ret;
18462
18463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18464     {
18465       if (unformat (i, "name %s", &match_name))
18466         {
18467           vec_add1 (match_name, 0);
18468           match_name_valid = 1;
18469         }
18470       else
18471         break;
18472     }
18473
18474   M (POLICER_DUMP, mp);
18475   mp->match_name_valid = match_name_valid;
18476   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18477   vec_free (match_name);
18478   /* send it... */
18479   S (mp);
18480
18481   /* Use a control ping for synchronization */
18482   MPING (CONTROL_PING, mp_ping);
18483   S (mp_ping);
18484
18485   /* Wait for a reply... */
18486   W (ret);
18487   return ret;
18488 }
18489
18490 static int
18491 api_policer_classify_set_interface (vat_main_t * vam)
18492 {
18493   unformat_input_t *i = vam->input;
18494   vl_api_policer_classify_set_interface_t *mp;
18495   u32 sw_if_index;
18496   int sw_if_index_set;
18497   u32 ip4_table_index = ~0;
18498   u32 ip6_table_index = ~0;
18499   u32 l2_table_index = ~0;
18500   u8 is_add = 1;
18501   int ret;
18502
18503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18504     {
18505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18506         sw_if_index_set = 1;
18507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18508         sw_if_index_set = 1;
18509       else if (unformat (i, "del"))
18510         is_add = 0;
18511       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18512         ;
18513       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18514         ;
18515       else if (unformat (i, "l2-table %d", &l2_table_index))
18516         ;
18517       else
18518         {
18519           clib_warning ("parse error '%U'", format_unformat_error, i);
18520           return -99;
18521         }
18522     }
18523
18524   if (sw_if_index_set == 0)
18525     {
18526       errmsg ("missing interface name or sw_if_index");
18527       return -99;
18528     }
18529
18530   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18531
18532   mp->sw_if_index = ntohl (sw_if_index);
18533   mp->ip4_table_index = ntohl (ip4_table_index);
18534   mp->ip6_table_index = ntohl (ip6_table_index);
18535   mp->l2_table_index = ntohl (l2_table_index);
18536   mp->is_add = is_add;
18537
18538   S (mp);
18539   W (ret);
18540   return ret;
18541 }
18542
18543 static int
18544 api_policer_classify_dump (vat_main_t * vam)
18545 {
18546   unformat_input_t *i = vam->input;
18547   vl_api_policer_classify_dump_t *mp;
18548   vl_api_control_ping_t *mp_ping;
18549   u8 type = POLICER_CLASSIFY_N_TABLES;
18550   int ret;
18551
18552   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18553     ;
18554   else
18555     {
18556       errmsg ("classify table type must be specified");
18557       return -99;
18558     }
18559
18560   if (!vam->json_output)
18561     {
18562       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18563     }
18564
18565   M (POLICER_CLASSIFY_DUMP, mp);
18566   mp->type = type;
18567   /* send it... */
18568   S (mp);
18569
18570   /* Use a control ping for synchronization */
18571   MPING (CONTROL_PING, mp_ping);
18572   S (mp_ping);
18573
18574   /* Wait for a reply... */
18575   W (ret);
18576   return ret;
18577 }
18578
18579 static int
18580 api_netmap_create (vat_main_t * vam)
18581 {
18582   unformat_input_t *i = vam->input;
18583   vl_api_netmap_create_t *mp;
18584   u8 *if_name = 0;
18585   u8 hw_addr[6];
18586   u8 random_hw_addr = 1;
18587   u8 is_pipe = 0;
18588   u8 is_master = 0;
18589   int ret;
18590
18591   clib_memset (hw_addr, 0, sizeof (hw_addr));
18592
18593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18594     {
18595       if (unformat (i, "name %s", &if_name))
18596         vec_add1 (if_name, 0);
18597       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18598         random_hw_addr = 0;
18599       else if (unformat (i, "pipe"))
18600         is_pipe = 1;
18601       else if (unformat (i, "master"))
18602         is_master = 1;
18603       else if (unformat (i, "slave"))
18604         is_master = 0;
18605       else
18606         break;
18607     }
18608
18609   if (!vec_len (if_name))
18610     {
18611       errmsg ("interface name must be specified");
18612       return -99;
18613     }
18614
18615   if (vec_len (if_name) > 64)
18616     {
18617       errmsg ("interface name too long");
18618       return -99;
18619     }
18620
18621   M (NETMAP_CREATE, mp);
18622
18623   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18624   clib_memcpy (mp->hw_addr, hw_addr, 6);
18625   mp->use_random_hw_addr = random_hw_addr;
18626   mp->is_pipe = is_pipe;
18627   mp->is_master = is_master;
18628   vec_free (if_name);
18629
18630   S (mp);
18631   W (ret);
18632   return ret;
18633 }
18634
18635 static int
18636 api_netmap_delete (vat_main_t * vam)
18637 {
18638   unformat_input_t *i = vam->input;
18639   vl_api_netmap_delete_t *mp;
18640   u8 *if_name = 0;
18641   int ret;
18642
18643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18644     {
18645       if (unformat (i, "name %s", &if_name))
18646         vec_add1 (if_name, 0);
18647       else
18648         break;
18649     }
18650
18651   if (!vec_len (if_name))
18652     {
18653       errmsg ("interface name must be specified");
18654       return -99;
18655     }
18656
18657   if (vec_len (if_name) > 64)
18658     {
18659       errmsg ("interface name too long");
18660       return -99;
18661     }
18662
18663   M (NETMAP_DELETE, mp);
18664
18665   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18666   vec_free (if_name);
18667
18668   S (mp);
18669   W (ret);
18670   return ret;
18671 }
18672
18673 static u8 *
18674 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18675 {
18676   vl_api_fib_path_nh_proto_t proto =
18677     va_arg (*args, vl_api_fib_path_nh_proto_t);
18678
18679   switch (proto)
18680     {
18681     case FIB_API_PATH_NH_PROTO_IP4:
18682       s = format (s, "ip4");
18683       break;
18684     case FIB_API_PATH_NH_PROTO_IP6:
18685       s = format (s, "ip6");
18686       break;
18687     case FIB_API_PATH_NH_PROTO_MPLS:
18688       s = format (s, "mpls");
18689       break;
18690     case FIB_API_PATH_NH_PROTO_BIER:
18691       s = format (s, "bier");
18692       break;
18693     case FIB_API_PATH_NH_PROTO_ETHERNET:
18694       s = format (s, "ethernet");
18695       break;
18696     }
18697
18698   return (s);
18699 }
18700
18701 static u8 *
18702 format_vl_api_ip_address_union (u8 * s, va_list * args)
18703 {
18704   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18705   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18706
18707   switch (af)
18708     {
18709     case ADDRESS_IP4:
18710       s = format (s, "%U", format_ip4_address, u->ip4);
18711       break;
18712     case ADDRESS_IP6:
18713       s = format (s, "%U", format_ip6_address, u->ip6);
18714       break;
18715     }
18716   return (s);
18717 }
18718
18719 static u8 *
18720 format_vl_api_fib_path_type (u8 * s, va_list * args)
18721 {
18722   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18723
18724   switch (t)
18725     {
18726     case FIB_API_PATH_TYPE_NORMAL:
18727       s = format (s, "normal");
18728       break;
18729     case FIB_API_PATH_TYPE_LOCAL:
18730       s = format (s, "local");
18731       break;
18732     case FIB_API_PATH_TYPE_DROP:
18733       s = format (s, "drop");
18734       break;
18735     case FIB_API_PATH_TYPE_UDP_ENCAP:
18736       s = format (s, "udp-encap");
18737       break;
18738     case FIB_API_PATH_TYPE_BIER_IMP:
18739       s = format (s, "bier-imp");
18740       break;
18741     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18742       s = format (s, "unreach");
18743       break;
18744     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18745       s = format (s, "prohibit");
18746       break;
18747     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18748       s = format (s, "src-lookup");
18749       break;
18750     case FIB_API_PATH_TYPE_DVR:
18751       s = format (s, "dvr");
18752       break;
18753     case FIB_API_PATH_TYPE_INTERFACE_RX:
18754       s = format (s, "interface-rx");
18755       break;
18756     case FIB_API_PATH_TYPE_CLASSIFY:
18757       s = format (s, "classify");
18758       break;
18759     }
18760
18761   return (s);
18762 }
18763
18764 static void
18765 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18766 {
18767   print (vam->ofp,
18768          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18769          ntohl (fp->weight), ntohl (fp->sw_if_index),
18770          format_vl_api_fib_path_type, fp->type,
18771          format_fib_api_path_nh_proto, fp->proto,
18772          format_vl_api_ip_address_union, &fp->nh.address);
18773 }
18774
18775 static void
18776 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18777                                  vl_api_fib_path_t * fp)
18778 {
18779   struct in_addr ip4;
18780   struct in6_addr ip6;
18781
18782   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18783   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18784   vat_json_object_add_uint (node, "type", fp->type);
18785   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18786   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18787     {
18788       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18789       vat_json_object_add_ip4 (node, "next_hop", ip4);
18790     }
18791   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18792     {
18793       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18794       vat_json_object_add_ip6 (node, "next_hop", ip6);
18795     }
18796 }
18797
18798 static void
18799 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18800 {
18801   vat_main_t *vam = &vat_main;
18802   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18803   vl_api_fib_path_t *fp;
18804   i32 i;
18805
18806   print (vam->ofp, "sw_if_index %d via:",
18807          ntohl (mp->mt_tunnel.mt_sw_if_index));
18808   fp = mp->mt_tunnel.mt_paths;
18809   for (i = 0; i < count; i++)
18810     {
18811       vl_api_fib_path_print (vam, fp);
18812       fp++;
18813     }
18814
18815   print (vam->ofp, "");
18816 }
18817
18818 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18819 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18820
18821 static void
18822 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18823 {
18824   vat_main_t *vam = &vat_main;
18825   vat_json_node_t *node = NULL;
18826   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18827   vl_api_fib_path_t *fp;
18828   i32 i;
18829
18830   if (VAT_JSON_ARRAY != vam->json_tree.type)
18831     {
18832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18833       vat_json_init_array (&vam->json_tree);
18834     }
18835   node = vat_json_array_add (&vam->json_tree);
18836
18837   vat_json_init_object (node);
18838   vat_json_object_add_uint (node, "sw_if_index",
18839                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18840
18841   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18842
18843   fp = mp->mt_tunnel.mt_paths;
18844   for (i = 0; i < count; i++)
18845     {
18846       vl_api_mpls_fib_path_json_print (node, fp);
18847       fp++;
18848     }
18849 }
18850
18851 static int
18852 api_mpls_tunnel_dump (vat_main_t * vam)
18853 {
18854   vl_api_mpls_tunnel_dump_t *mp;
18855   vl_api_control_ping_t *mp_ping;
18856   int ret;
18857
18858   M (MPLS_TUNNEL_DUMP, mp);
18859
18860   S (mp);
18861
18862   /* Use a control ping for synchronization */
18863   MPING (CONTROL_PING, mp_ping);
18864   S (mp_ping);
18865
18866   W (ret);
18867   return ret;
18868 }
18869
18870 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18871 #define vl_api_mpls_table_details_t_print vl_noop_handler
18872
18873
18874 static void
18875 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18876 {
18877   vat_main_t *vam = &vat_main;
18878
18879   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18880 }
18881
18882 static void vl_api_mpls_table_details_t_handler_json
18883   (vl_api_mpls_table_details_t * mp)
18884 {
18885   vat_main_t *vam = &vat_main;
18886   vat_json_node_t *node = NULL;
18887
18888   if (VAT_JSON_ARRAY != vam->json_tree.type)
18889     {
18890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18891       vat_json_init_array (&vam->json_tree);
18892     }
18893   node = vat_json_array_add (&vam->json_tree);
18894
18895   vat_json_init_object (node);
18896   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18897 }
18898
18899 static int
18900 api_mpls_table_dump (vat_main_t * vam)
18901 {
18902   vl_api_mpls_table_dump_t *mp;
18903   vl_api_control_ping_t *mp_ping;
18904   int ret;
18905
18906   M (MPLS_TABLE_DUMP, mp);
18907   S (mp);
18908
18909   /* Use a control ping for synchronization */
18910   MPING (CONTROL_PING, mp_ping);
18911   S (mp_ping);
18912
18913   W (ret);
18914   return ret;
18915 }
18916
18917 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18918 #define vl_api_mpls_route_details_t_print vl_noop_handler
18919
18920 static void
18921 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18922 {
18923   vat_main_t *vam = &vat_main;
18924   int count = ntohl (mp->mr_route.mr_n_paths);
18925   vl_api_fib_path_t *fp;
18926   int i;
18927
18928   print (vam->ofp,
18929          "table-id %d, label %u, ess_bit %u",
18930          ntohl (mp->mr_route.mr_table_id),
18931          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18932   fp = mp->mr_route.mr_paths;
18933   for (i = 0; i < count; i++)
18934     {
18935       vl_api_fib_path_print (vam, fp);
18936       fp++;
18937     }
18938 }
18939
18940 static void vl_api_mpls_route_details_t_handler_json
18941   (vl_api_mpls_route_details_t * mp)
18942 {
18943   vat_main_t *vam = &vat_main;
18944   int count = ntohl (mp->mr_route.mr_n_paths);
18945   vat_json_node_t *node = NULL;
18946   vl_api_fib_path_t *fp;
18947   int i;
18948
18949   if (VAT_JSON_ARRAY != vam->json_tree.type)
18950     {
18951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18952       vat_json_init_array (&vam->json_tree);
18953     }
18954   node = vat_json_array_add (&vam->json_tree);
18955
18956   vat_json_init_object (node);
18957   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18958   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18959   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18960   vat_json_object_add_uint (node, "path_count", count);
18961   fp = mp->mr_route.mr_paths;
18962   for (i = 0; i < count; i++)
18963     {
18964       vl_api_mpls_fib_path_json_print (node, fp);
18965       fp++;
18966     }
18967 }
18968
18969 static int
18970 api_mpls_route_dump (vat_main_t * vam)
18971 {
18972   unformat_input_t *input = vam->input;
18973   vl_api_mpls_route_dump_t *mp;
18974   vl_api_control_ping_t *mp_ping;
18975   u32 table_id;
18976   int ret;
18977
18978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18979     {
18980       if (unformat (input, "table_id %d", &table_id))
18981         ;
18982       else
18983         break;
18984     }
18985   if (table_id == ~0)
18986     {
18987       errmsg ("missing table id");
18988       return -99;
18989     }
18990
18991   M (MPLS_ROUTE_DUMP, mp);
18992
18993   mp->table.mt_table_id = ntohl (table_id);
18994   S (mp);
18995
18996   /* Use a control ping for synchronization */
18997   MPING (CONTROL_PING, mp_ping);
18998   S (mp_ping);
18999
19000   W (ret);
19001   return ret;
19002 }
19003
19004 #define vl_api_ip_table_details_t_endian vl_noop_handler
19005 #define vl_api_ip_table_details_t_print vl_noop_handler
19006
19007 static void
19008 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19009 {
19010   vat_main_t *vam = &vat_main;
19011
19012   print (vam->ofp,
19013          "%s; table-id %d, prefix %U/%d",
19014          mp->table.name, ntohl (mp->table.table_id));
19015 }
19016
19017
19018 static void vl_api_ip_table_details_t_handler_json
19019   (vl_api_ip_table_details_t * mp)
19020 {
19021   vat_main_t *vam = &vat_main;
19022   vat_json_node_t *node = NULL;
19023
19024   if (VAT_JSON_ARRAY != vam->json_tree.type)
19025     {
19026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19027       vat_json_init_array (&vam->json_tree);
19028     }
19029   node = vat_json_array_add (&vam->json_tree);
19030
19031   vat_json_init_object (node);
19032   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19033 }
19034
19035 static int
19036 api_ip_table_dump (vat_main_t * vam)
19037 {
19038   vl_api_ip_table_dump_t *mp;
19039   vl_api_control_ping_t *mp_ping;
19040   int ret;
19041
19042   M (IP_TABLE_DUMP, mp);
19043   S (mp);
19044
19045   /* Use a control ping for synchronization */
19046   MPING (CONTROL_PING, mp_ping);
19047   S (mp_ping);
19048
19049   W (ret);
19050   return ret;
19051 }
19052
19053 static int
19054 api_ip_mtable_dump (vat_main_t * vam)
19055 {
19056   vl_api_ip_mtable_dump_t *mp;
19057   vl_api_control_ping_t *mp_ping;
19058   int ret;
19059
19060   M (IP_MTABLE_DUMP, mp);
19061   S (mp);
19062
19063   /* Use a control ping for synchronization */
19064   MPING (CONTROL_PING, mp_ping);
19065   S (mp_ping);
19066
19067   W (ret);
19068   return ret;
19069 }
19070
19071 static int
19072 api_ip_mroute_dump (vat_main_t * vam)
19073 {
19074   unformat_input_t *input = vam->input;
19075   vl_api_control_ping_t *mp_ping;
19076   vl_api_ip_mroute_dump_t *mp;
19077   int ret, is_ip6;
19078   u32 table_id;
19079
19080   is_ip6 = 0;
19081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19082     {
19083       if (unformat (input, "table_id %d", &table_id))
19084         ;
19085       else if (unformat (input, "ip6"))
19086         is_ip6 = 1;
19087       else if (unformat (input, "ip4"))
19088         is_ip6 = 0;
19089       else
19090         break;
19091     }
19092   if (table_id == ~0)
19093     {
19094       errmsg ("missing table id");
19095       return -99;
19096     }
19097
19098   M (IP_MROUTE_DUMP, mp);
19099   mp->table.table_id = table_id;
19100   mp->table.is_ip6 = is_ip6;
19101   S (mp);
19102
19103   /* Use a control ping for synchronization */
19104   MPING (CONTROL_PING, mp_ping);
19105   S (mp_ping);
19106
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static void vl_api_ip_neighbor_details_t_handler
19112   (vl_api_ip_neighbor_details_t * mp)
19113 {
19114   vat_main_t *vam = &vat_main;
19115
19116   print (vam->ofp, "%c %U %U",
19117          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19118          format_vl_api_mac_address, &mp->neighbor.mac_address,
19119          format_vl_api_address, &mp->neighbor.ip_address);
19120 }
19121
19122 static void vl_api_ip_neighbor_details_t_handler_json
19123   (vl_api_ip_neighbor_details_t * mp)
19124 {
19125
19126   vat_main_t *vam = &vat_main;
19127   vat_json_node_t *node;
19128
19129   if (VAT_JSON_ARRAY != vam->json_tree.type)
19130     {
19131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19132       vat_json_init_array (&vam->json_tree);
19133     }
19134   node = vat_json_array_add (&vam->json_tree);
19135
19136   vat_json_init_object (node);
19137   vat_json_object_add_string_copy
19138     (node, "flag",
19139      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19140       (u8 *) "static" : (u8 *) "dynamic"));
19141
19142   vat_json_object_add_string_copy (node, "link_layer",
19143                                    format (0, "%U", format_vl_api_mac_address,
19144                                            &mp->neighbor.mac_address));
19145   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19146 }
19147
19148 static int
19149 api_ip_neighbor_dump (vat_main_t * vam)
19150 {
19151   unformat_input_t *i = vam->input;
19152   vl_api_ip_neighbor_dump_t *mp;
19153   vl_api_control_ping_t *mp_ping;
19154   u8 is_ipv6 = 0;
19155   u32 sw_if_index = ~0;
19156   int ret;
19157
19158   /* Parse args required to build the message */
19159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19160     {
19161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19162         ;
19163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19164         ;
19165       else if (unformat (i, "ip6"))
19166         is_ipv6 = 1;
19167       else
19168         break;
19169     }
19170
19171   if (sw_if_index == ~0)
19172     {
19173       errmsg ("missing interface name or sw_if_index");
19174       return -99;
19175     }
19176
19177   M (IP_NEIGHBOR_DUMP, mp);
19178   mp->is_ipv6 = (u8) is_ipv6;
19179   mp->sw_if_index = ntohl (sw_if_index);
19180   S (mp);
19181
19182   /* Use a control ping for synchronization */
19183   MPING (CONTROL_PING, mp_ping);
19184   S (mp_ping);
19185
19186   W (ret);
19187   return ret;
19188 }
19189
19190 #define vl_api_ip_route_details_t_endian vl_noop_handler
19191 #define vl_api_ip_route_details_t_print vl_noop_handler
19192
19193 static void
19194 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19195 {
19196   vat_main_t *vam = &vat_main;
19197   u8 count = mp->route.n_paths;
19198   vl_api_fib_path_t *fp;
19199   int i;
19200
19201   print (vam->ofp,
19202          "table-id %d, prefix %U/%d",
19203          ntohl (mp->route.table_id),
19204          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19205   for (i = 0; i < count; i++)
19206     {
19207       fp = &mp->route.paths[i];
19208
19209       vl_api_fib_path_print (vam, fp);
19210       fp++;
19211     }
19212 }
19213
19214 static void vl_api_ip_route_details_t_handler_json
19215   (vl_api_ip_route_details_t * mp)
19216 {
19217   vat_main_t *vam = &vat_main;
19218   u8 count = mp->route.n_paths;
19219   vat_json_node_t *node = NULL;
19220   struct in_addr ip4;
19221   struct in6_addr ip6;
19222   vl_api_fib_path_t *fp;
19223   int i;
19224
19225   if (VAT_JSON_ARRAY != vam->json_tree.type)
19226     {
19227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19228       vat_json_init_array (&vam->json_tree);
19229     }
19230   node = vat_json_array_add (&vam->json_tree);
19231
19232   vat_json_init_object (node);
19233   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19234   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19235     {
19236       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19237       vat_json_object_add_ip6 (node, "prefix", ip6);
19238     }
19239   else
19240     {
19241       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19242       vat_json_object_add_ip4 (node, "prefix", ip4);
19243     }
19244   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19245   vat_json_object_add_uint (node, "path_count", count);
19246   for (i = 0; i < count; i++)
19247     {
19248       fp = &mp->route.paths[i];
19249       vl_api_mpls_fib_path_json_print (node, fp);
19250     }
19251 }
19252
19253 static int
19254 api_ip_route_dump (vat_main_t * vam)
19255 {
19256   unformat_input_t *input = vam->input;
19257   vl_api_ip_route_dump_t *mp;
19258   vl_api_control_ping_t *mp_ping;
19259   u32 table_id;
19260   u8 is_ip6;
19261   int ret;
19262
19263   is_ip6 = 0;
19264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19265     {
19266       if (unformat (input, "table_id %d", &table_id))
19267         ;
19268       else if (unformat (input, "ip6"))
19269         is_ip6 = 1;
19270       else if (unformat (input, "ip4"))
19271         is_ip6 = 0;
19272       else
19273         break;
19274     }
19275   if (table_id == ~0)
19276     {
19277       errmsg ("missing table id");
19278       return -99;
19279     }
19280
19281   M (IP_ROUTE_DUMP, mp);
19282
19283   mp->table.table_id = table_id;
19284   mp->table.is_ip6 = is_ip6;
19285
19286   S (mp);
19287
19288   /* Use a control ping for synchronization */
19289   MPING (CONTROL_PING, mp_ping);
19290   S (mp_ping);
19291
19292   W (ret);
19293   return ret;
19294 }
19295
19296 int
19297 api_classify_table_ids (vat_main_t * vam)
19298 {
19299   vl_api_classify_table_ids_t *mp;
19300   int ret;
19301
19302   /* Construct the API message */
19303   M (CLASSIFY_TABLE_IDS, mp);
19304   mp->context = 0;
19305
19306   S (mp);
19307   W (ret);
19308   return ret;
19309 }
19310
19311 int
19312 api_classify_table_by_interface (vat_main_t * vam)
19313 {
19314   unformat_input_t *input = vam->input;
19315   vl_api_classify_table_by_interface_t *mp;
19316
19317   u32 sw_if_index = ~0;
19318   int ret;
19319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19320     {
19321       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19322         ;
19323       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19324         ;
19325       else
19326         break;
19327     }
19328   if (sw_if_index == ~0)
19329     {
19330       errmsg ("missing interface name or sw_if_index");
19331       return -99;
19332     }
19333
19334   /* Construct the API message */
19335   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19336   mp->context = 0;
19337   mp->sw_if_index = ntohl (sw_if_index);
19338
19339   S (mp);
19340   W (ret);
19341   return ret;
19342 }
19343
19344 int
19345 api_classify_table_info (vat_main_t * vam)
19346 {
19347   unformat_input_t *input = vam->input;
19348   vl_api_classify_table_info_t *mp;
19349
19350   u32 table_id = ~0;
19351   int ret;
19352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19353     {
19354       if (unformat (input, "table_id %d", &table_id))
19355         ;
19356       else
19357         break;
19358     }
19359   if (table_id == ~0)
19360     {
19361       errmsg ("missing table id");
19362       return -99;
19363     }
19364
19365   /* Construct the API message */
19366   M (CLASSIFY_TABLE_INFO, mp);
19367   mp->context = 0;
19368   mp->table_id = ntohl (table_id);
19369
19370   S (mp);
19371   W (ret);
19372   return ret;
19373 }
19374
19375 int
19376 api_classify_session_dump (vat_main_t * vam)
19377 {
19378   unformat_input_t *input = vam->input;
19379   vl_api_classify_session_dump_t *mp;
19380   vl_api_control_ping_t *mp_ping;
19381
19382   u32 table_id = ~0;
19383   int ret;
19384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19385     {
19386       if (unformat (input, "table_id %d", &table_id))
19387         ;
19388       else
19389         break;
19390     }
19391   if (table_id == ~0)
19392     {
19393       errmsg ("missing table id");
19394       return -99;
19395     }
19396
19397   /* Construct the API message */
19398   M (CLASSIFY_SESSION_DUMP, mp);
19399   mp->context = 0;
19400   mp->table_id = ntohl (table_id);
19401   S (mp);
19402
19403   /* Use a control ping for synchronization */
19404   MPING (CONTROL_PING, mp_ping);
19405   S (mp_ping);
19406
19407   W (ret);
19408   return ret;
19409 }
19410
19411 static void
19412 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19413 {
19414   vat_main_t *vam = &vat_main;
19415
19416   print (vam->ofp, "collector_address %U, collector_port %d, "
19417          "src_address %U, vrf_id %d, path_mtu %u, "
19418          "template_interval %u, udp_checksum %d",
19419          format_ip4_address, mp->collector_address,
19420          ntohs (mp->collector_port),
19421          format_ip4_address, mp->src_address,
19422          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19423          ntohl (mp->template_interval), mp->udp_checksum);
19424
19425   vam->retval = 0;
19426   vam->result_ready = 1;
19427 }
19428
19429 static void
19430   vl_api_ipfix_exporter_details_t_handler_json
19431   (vl_api_ipfix_exporter_details_t * mp)
19432 {
19433   vat_main_t *vam = &vat_main;
19434   vat_json_node_t node;
19435   struct in_addr collector_address;
19436   struct in_addr src_address;
19437
19438   vat_json_init_object (&node);
19439   clib_memcpy (&collector_address, &mp->collector_address,
19440                sizeof (collector_address));
19441   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19442   vat_json_object_add_uint (&node, "collector_port",
19443                             ntohs (mp->collector_port));
19444   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19445   vat_json_object_add_ip4 (&node, "src_address", src_address);
19446   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19447   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19448   vat_json_object_add_uint (&node, "template_interval",
19449                             ntohl (mp->template_interval));
19450   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19451
19452   vat_json_print (vam->ofp, &node);
19453   vat_json_free (&node);
19454   vam->retval = 0;
19455   vam->result_ready = 1;
19456 }
19457
19458 int
19459 api_ipfix_exporter_dump (vat_main_t * vam)
19460 {
19461   vl_api_ipfix_exporter_dump_t *mp;
19462   int ret;
19463
19464   /* Construct the API message */
19465   M (IPFIX_EXPORTER_DUMP, mp);
19466   mp->context = 0;
19467
19468   S (mp);
19469   W (ret);
19470   return ret;
19471 }
19472
19473 static int
19474 api_ipfix_classify_stream_dump (vat_main_t * vam)
19475 {
19476   vl_api_ipfix_classify_stream_dump_t *mp;
19477   int ret;
19478
19479   /* Construct the API message */
19480   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19481   mp->context = 0;
19482
19483   S (mp);
19484   W (ret);
19485   return ret;
19486   /* NOTREACHED */
19487   return 0;
19488 }
19489
19490 static void
19491   vl_api_ipfix_classify_stream_details_t_handler
19492   (vl_api_ipfix_classify_stream_details_t * mp)
19493 {
19494   vat_main_t *vam = &vat_main;
19495   print (vam->ofp, "domain_id %d, src_port %d",
19496          ntohl (mp->domain_id), ntohs (mp->src_port));
19497   vam->retval = 0;
19498   vam->result_ready = 1;
19499 }
19500
19501 static void
19502   vl_api_ipfix_classify_stream_details_t_handler_json
19503   (vl_api_ipfix_classify_stream_details_t * mp)
19504 {
19505   vat_main_t *vam = &vat_main;
19506   vat_json_node_t node;
19507
19508   vat_json_init_object (&node);
19509   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19510   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19511
19512   vat_json_print (vam->ofp, &node);
19513   vat_json_free (&node);
19514   vam->retval = 0;
19515   vam->result_ready = 1;
19516 }
19517
19518 static int
19519 api_ipfix_classify_table_dump (vat_main_t * vam)
19520 {
19521   vl_api_ipfix_classify_table_dump_t *mp;
19522   vl_api_control_ping_t *mp_ping;
19523   int ret;
19524
19525   if (!vam->json_output)
19526     {
19527       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19528              "transport_protocol");
19529     }
19530
19531   /* Construct the API message */
19532   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19533
19534   /* send it... */
19535   S (mp);
19536
19537   /* Use a control ping for synchronization */
19538   MPING (CONTROL_PING, mp_ping);
19539   S (mp_ping);
19540
19541   W (ret);
19542   return ret;
19543 }
19544
19545 static void
19546   vl_api_ipfix_classify_table_details_t_handler
19547   (vl_api_ipfix_classify_table_details_t * mp)
19548 {
19549   vat_main_t *vam = &vat_main;
19550   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19551          mp->transport_protocol);
19552 }
19553
19554 static void
19555   vl_api_ipfix_classify_table_details_t_handler_json
19556   (vl_api_ipfix_classify_table_details_t * mp)
19557 {
19558   vat_json_node_t *node = NULL;
19559   vat_main_t *vam = &vat_main;
19560
19561   if (VAT_JSON_ARRAY != vam->json_tree.type)
19562     {
19563       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19564       vat_json_init_array (&vam->json_tree);
19565     }
19566
19567   node = vat_json_array_add (&vam->json_tree);
19568   vat_json_init_object (node);
19569
19570   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19571   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19572   vat_json_object_add_uint (node, "transport_protocol",
19573                             mp->transport_protocol);
19574 }
19575
19576 static int
19577 api_sw_interface_span_enable_disable (vat_main_t * vam)
19578 {
19579   unformat_input_t *i = vam->input;
19580   vl_api_sw_interface_span_enable_disable_t *mp;
19581   u32 src_sw_if_index = ~0;
19582   u32 dst_sw_if_index = ~0;
19583   u8 state = 3;
19584   int ret;
19585   u8 is_l2 = 0;
19586
19587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19588     {
19589       if (unformat
19590           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19591         ;
19592       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19593         ;
19594       else
19595         if (unformat
19596             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19597         ;
19598       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19599         ;
19600       else if (unformat (i, "disable"))
19601         state = 0;
19602       else if (unformat (i, "rx"))
19603         state = 1;
19604       else if (unformat (i, "tx"))
19605         state = 2;
19606       else if (unformat (i, "both"))
19607         state = 3;
19608       else if (unformat (i, "l2"))
19609         is_l2 = 1;
19610       else
19611         break;
19612     }
19613
19614   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19615
19616   mp->sw_if_index_from = htonl (src_sw_if_index);
19617   mp->sw_if_index_to = htonl (dst_sw_if_index);
19618   mp->state = state;
19619   mp->is_l2 = is_l2;
19620
19621   S (mp);
19622   W (ret);
19623   return ret;
19624 }
19625
19626 static void
19627 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19628                                             * mp)
19629 {
19630   vat_main_t *vam = &vat_main;
19631   u8 *sw_if_from_name = 0;
19632   u8 *sw_if_to_name = 0;
19633   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19634   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19635   char *states[] = { "none", "rx", "tx", "both" };
19636   hash_pair_t *p;
19637
19638   /* *INDENT-OFF* */
19639   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19640   ({
19641     if ((u32) p->value[0] == sw_if_index_from)
19642       {
19643         sw_if_from_name = (u8 *)(p->key);
19644         if (sw_if_to_name)
19645           break;
19646       }
19647     if ((u32) p->value[0] == sw_if_index_to)
19648       {
19649         sw_if_to_name = (u8 *)(p->key);
19650         if (sw_if_from_name)
19651           break;
19652       }
19653   }));
19654   /* *INDENT-ON* */
19655   print (vam->ofp, "%20s => %20s (%s) %s",
19656          sw_if_from_name, sw_if_to_name, states[mp->state],
19657          mp->is_l2 ? "l2" : "device");
19658 }
19659
19660 static void
19661   vl_api_sw_interface_span_details_t_handler_json
19662   (vl_api_sw_interface_span_details_t * mp)
19663 {
19664   vat_main_t *vam = &vat_main;
19665   vat_json_node_t *node = NULL;
19666   u8 *sw_if_from_name = 0;
19667   u8 *sw_if_to_name = 0;
19668   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19669   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19670   hash_pair_t *p;
19671
19672   /* *INDENT-OFF* */
19673   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19674   ({
19675     if ((u32) p->value[0] == sw_if_index_from)
19676       {
19677         sw_if_from_name = (u8 *)(p->key);
19678         if (sw_if_to_name)
19679           break;
19680       }
19681     if ((u32) p->value[0] == sw_if_index_to)
19682       {
19683         sw_if_to_name = (u8 *)(p->key);
19684         if (sw_if_from_name)
19685           break;
19686       }
19687   }));
19688   /* *INDENT-ON* */
19689
19690   if (VAT_JSON_ARRAY != vam->json_tree.type)
19691     {
19692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19693       vat_json_init_array (&vam->json_tree);
19694     }
19695   node = vat_json_array_add (&vam->json_tree);
19696
19697   vat_json_init_object (node);
19698   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19699   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19700   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19701   if (0 != sw_if_to_name)
19702     {
19703       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19704     }
19705   vat_json_object_add_uint (node, "state", mp->state);
19706   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19707 }
19708
19709 static int
19710 api_sw_interface_span_dump (vat_main_t * vam)
19711 {
19712   unformat_input_t *input = vam->input;
19713   vl_api_sw_interface_span_dump_t *mp;
19714   vl_api_control_ping_t *mp_ping;
19715   u8 is_l2 = 0;
19716   int ret;
19717
19718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19719     {
19720       if (unformat (input, "l2"))
19721         is_l2 = 1;
19722       else
19723         break;
19724     }
19725
19726   M (SW_INTERFACE_SPAN_DUMP, mp);
19727   mp->is_l2 = is_l2;
19728   S (mp);
19729
19730   /* Use a control ping for synchronization */
19731   MPING (CONTROL_PING, mp_ping);
19732   S (mp_ping);
19733
19734   W (ret);
19735   return ret;
19736 }
19737
19738 int
19739 api_pg_create_interface (vat_main_t * vam)
19740 {
19741   unformat_input_t *input = vam->input;
19742   vl_api_pg_create_interface_t *mp;
19743
19744   u32 if_id = ~0;
19745   int ret;
19746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19747     {
19748       if (unformat (input, "if_id %d", &if_id))
19749         ;
19750       else
19751         break;
19752     }
19753   if (if_id == ~0)
19754     {
19755       errmsg ("missing pg interface index");
19756       return -99;
19757     }
19758
19759   /* Construct the API message */
19760   M (PG_CREATE_INTERFACE, mp);
19761   mp->context = 0;
19762   mp->interface_id = ntohl (if_id);
19763
19764   S (mp);
19765   W (ret);
19766   return ret;
19767 }
19768
19769 int
19770 api_pg_capture (vat_main_t * vam)
19771 {
19772   unformat_input_t *input = vam->input;
19773   vl_api_pg_capture_t *mp;
19774
19775   u32 if_id = ~0;
19776   u8 enable = 1;
19777   u32 count = 1;
19778   u8 pcap_file_set = 0;
19779   u8 *pcap_file = 0;
19780   int ret;
19781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19782     {
19783       if (unformat (input, "if_id %d", &if_id))
19784         ;
19785       else if (unformat (input, "pcap %s", &pcap_file))
19786         pcap_file_set = 1;
19787       else if (unformat (input, "count %d", &count))
19788         ;
19789       else if (unformat (input, "disable"))
19790         enable = 0;
19791       else
19792         break;
19793     }
19794   if (if_id == ~0)
19795     {
19796       errmsg ("missing pg interface index");
19797       return -99;
19798     }
19799   if (pcap_file_set > 0)
19800     {
19801       if (vec_len (pcap_file) > 255)
19802         {
19803           errmsg ("pcap file name is too long");
19804           return -99;
19805         }
19806     }
19807
19808   u32 name_len = vec_len (pcap_file);
19809   /* Construct the API message */
19810   M (PG_CAPTURE, mp);
19811   mp->context = 0;
19812   mp->interface_id = ntohl (if_id);
19813   mp->is_enabled = enable;
19814   mp->count = ntohl (count);
19815   mp->pcap_name_length = ntohl (name_len);
19816   if (pcap_file_set != 0)
19817     {
19818       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19819     }
19820   vec_free (pcap_file);
19821
19822   S (mp);
19823   W (ret);
19824   return ret;
19825 }
19826
19827 int
19828 api_pg_enable_disable (vat_main_t * vam)
19829 {
19830   unformat_input_t *input = vam->input;
19831   vl_api_pg_enable_disable_t *mp;
19832
19833   u8 enable = 1;
19834   u8 stream_name_set = 0;
19835   u8 *stream_name = 0;
19836   int ret;
19837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19838     {
19839       if (unformat (input, "stream %s", &stream_name))
19840         stream_name_set = 1;
19841       else if (unformat (input, "disable"))
19842         enable = 0;
19843       else
19844         break;
19845     }
19846
19847   if (stream_name_set > 0)
19848     {
19849       if (vec_len (stream_name) > 255)
19850         {
19851           errmsg ("stream name too long");
19852           return -99;
19853         }
19854     }
19855
19856   u32 name_len = vec_len (stream_name);
19857   /* Construct the API message */
19858   M (PG_ENABLE_DISABLE, mp);
19859   mp->context = 0;
19860   mp->is_enabled = enable;
19861   if (stream_name_set != 0)
19862     {
19863       mp->stream_name_length = ntohl (name_len);
19864       clib_memcpy (mp->stream_name, stream_name, name_len);
19865     }
19866   vec_free (stream_name);
19867
19868   S (mp);
19869   W (ret);
19870   return ret;
19871 }
19872
19873 int
19874 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19875 {
19876   unformat_input_t *input = vam->input;
19877   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19878
19879   u16 *low_ports = 0;
19880   u16 *high_ports = 0;
19881   u16 this_low;
19882   u16 this_hi;
19883   vl_api_prefix_t prefix;
19884   u32 tmp, tmp2;
19885   u8 prefix_set = 0;
19886   u32 vrf_id = ~0;
19887   u8 is_add = 1;
19888   int ret;
19889
19890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19891     {
19892       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19893         prefix_set = 1;
19894       else if (unformat (input, "vrf %d", &vrf_id))
19895         ;
19896       else if (unformat (input, "del"))
19897         is_add = 0;
19898       else if (unformat (input, "port %d", &tmp))
19899         {
19900           if (tmp == 0 || tmp > 65535)
19901             {
19902               errmsg ("port %d out of range", tmp);
19903               return -99;
19904             }
19905           this_low = tmp;
19906           this_hi = this_low + 1;
19907           vec_add1 (low_ports, this_low);
19908           vec_add1 (high_ports, this_hi);
19909         }
19910       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19911         {
19912           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19913             {
19914               errmsg ("incorrect range parameters");
19915               return -99;
19916             }
19917           this_low = tmp;
19918           /* Note: in debug CLI +1 is added to high before
19919              passing to real fn that does "the work"
19920              (ip_source_and_port_range_check_add_del).
19921              This fn is a wrapper around the binary API fn a
19922              control plane will call, which expects this increment
19923              to have occurred. Hence letting the binary API control
19924              plane fn do the increment for consistency between VAT
19925              and other control planes.
19926            */
19927           this_hi = tmp2;
19928           vec_add1 (low_ports, this_low);
19929           vec_add1 (high_ports, this_hi);
19930         }
19931       else
19932         break;
19933     }
19934
19935   if (prefix_set == 0)
19936     {
19937       errmsg ("<address>/<mask> not specified");
19938       return -99;
19939     }
19940
19941   if (vrf_id == ~0)
19942     {
19943       errmsg ("VRF ID required, not specified");
19944       return -99;
19945     }
19946
19947   if (vrf_id == 0)
19948     {
19949       errmsg
19950         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19951       return -99;
19952     }
19953
19954   if (vec_len (low_ports) == 0)
19955     {
19956       errmsg ("At least one port or port range required");
19957       return -99;
19958     }
19959
19960   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19961
19962   mp->is_add = is_add;
19963
19964   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19965
19966   mp->number_of_ranges = vec_len (low_ports);
19967
19968   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19969   vec_free (low_ports);
19970
19971   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19972   vec_free (high_ports);
19973
19974   mp->vrf_id = ntohl (vrf_id);
19975
19976   S (mp);
19977   W (ret);
19978   return ret;
19979 }
19980
19981 int
19982 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19983 {
19984   unformat_input_t *input = vam->input;
19985   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19986   u32 sw_if_index = ~0;
19987   int vrf_set = 0;
19988   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19989   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19990   u8 is_add = 1;
19991   int ret;
19992
19993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19994     {
19995       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19996         ;
19997       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19998         ;
19999       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20000         vrf_set = 1;
20001       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20002         vrf_set = 1;
20003       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20004         vrf_set = 1;
20005       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20006         vrf_set = 1;
20007       else if (unformat (input, "del"))
20008         is_add = 0;
20009       else
20010         break;
20011     }
20012
20013   if (sw_if_index == ~0)
20014     {
20015       errmsg ("Interface required but not specified");
20016       return -99;
20017     }
20018
20019   if (vrf_set == 0)
20020     {
20021       errmsg ("VRF ID required but not specified");
20022       return -99;
20023     }
20024
20025   if (tcp_out_vrf_id == 0
20026       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20027     {
20028       errmsg
20029         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20030       return -99;
20031     }
20032
20033   /* Construct the API message */
20034   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20035
20036   mp->sw_if_index = ntohl (sw_if_index);
20037   mp->is_add = is_add;
20038   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20039   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20040   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20041   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20042
20043   /* send it... */
20044   S (mp);
20045
20046   /* Wait for a reply... */
20047   W (ret);
20048   return ret;
20049 }
20050
20051 static int
20052 api_set_punt (vat_main_t * vam)
20053 {
20054   unformat_input_t *i = vam->input;
20055   vl_api_address_family_t af;
20056   vl_api_set_punt_t *mp;
20057   u32 protocol = ~0;
20058   u32 port = ~0;
20059   int is_add = 1;
20060   int ret;
20061
20062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20063     {
20064       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20065         ;
20066       else if (unformat (i, "protocol %d", &protocol))
20067         ;
20068       else if (unformat (i, "port %d", &port))
20069         ;
20070       else if (unformat (i, "del"))
20071         is_add = 0;
20072       else
20073         {
20074           clib_warning ("parse error '%U'", format_unformat_error, i);
20075           return -99;
20076         }
20077     }
20078
20079   M (SET_PUNT, mp);
20080
20081   mp->is_add = (u8) is_add;
20082   mp->punt.type = PUNT_API_TYPE_L4;
20083   mp->punt.punt.l4.af = af;
20084   mp->punt.punt.l4.protocol = (u8) protocol;
20085   mp->punt.punt.l4.port = htons ((u16) port);
20086
20087   S (mp);
20088   W (ret);
20089   return ret;
20090 }
20091
20092 static int
20093 api_delete_subif (vat_main_t * vam)
20094 {
20095   unformat_input_t *i = vam->input;
20096   vl_api_delete_subif_t *mp;
20097   u32 sw_if_index = ~0;
20098   int ret;
20099
20100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20101     {
20102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20103         ;
20104       if (unformat (i, "sw_if_index %d", &sw_if_index))
20105         ;
20106       else
20107         break;
20108     }
20109
20110   if (sw_if_index == ~0)
20111     {
20112       errmsg ("missing sw_if_index");
20113       return -99;
20114     }
20115
20116   /* Construct the API message */
20117   M (DELETE_SUBIF, mp);
20118   mp->sw_if_index = ntohl (sw_if_index);
20119
20120   S (mp);
20121   W (ret);
20122   return ret;
20123 }
20124
20125 #define foreach_pbb_vtr_op      \
20126 _("disable",  L2_VTR_DISABLED)  \
20127 _("pop",  L2_VTR_POP_2)         \
20128 _("push",  L2_VTR_PUSH_2)
20129
20130 static int
20131 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20132 {
20133   unformat_input_t *i = vam->input;
20134   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20135   u32 sw_if_index = ~0, vtr_op = ~0;
20136   u16 outer_tag = ~0;
20137   u8 dmac[6], smac[6];
20138   u8 dmac_set = 0, smac_set = 0;
20139   u16 vlanid = 0;
20140   u32 sid = ~0;
20141   u32 tmp;
20142   int ret;
20143
20144   /* Shut up coverity */
20145   clib_memset (dmac, 0, sizeof (dmac));
20146   clib_memset (smac, 0, sizeof (smac));
20147
20148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20149     {
20150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20151         ;
20152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20153         ;
20154       else if (unformat (i, "vtr_op %d", &vtr_op))
20155         ;
20156 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20157       foreach_pbb_vtr_op
20158 #undef _
20159         else if (unformat (i, "translate_pbb_stag"))
20160         {
20161           if (unformat (i, "%d", &tmp))
20162             {
20163               vtr_op = L2_VTR_TRANSLATE_2_1;
20164               outer_tag = tmp;
20165             }
20166           else
20167             {
20168               errmsg
20169                 ("translate_pbb_stag operation requires outer tag definition");
20170               return -99;
20171             }
20172         }
20173       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20174         dmac_set++;
20175       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20176         smac_set++;
20177       else if (unformat (i, "sid %d", &sid))
20178         ;
20179       else if (unformat (i, "vlanid %d", &tmp))
20180         vlanid = tmp;
20181       else
20182         {
20183           clib_warning ("parse error '%U'", format_unformat_error, i);
20184           return -99;
20185         }
20186     }
20187
20188   if ((sw_if_index == ~0) || (vtr_op == ~0))
20189     {
20190       errmsg ("missing sw_if_index or vtr operation");
20191       return -99;
20192     }
20193   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20194       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20195     {
20196       errmsg
20197         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20198       return -99;
20199     }
20200
20201   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20202   mp->sw_if_index = ntohl (sw_if_index);
20203   mp->vtr_op = ntohl (vtr_op);
20204   mp->outer_tag = ntohs (outer_tag);
20205   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20206   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20207   mp->b_vlanid = ntohs (vlanid);
20208   mp->i_sid = ntohl (sid);
20209
20210   S (mp);
20211   W (ret);
20212   return ret;
20213 }
20214
20215 static int
20216 api_flow_classify_set_interface (vat_main_t * vam)
20217 {
20218   unformat_input_t *i = vam->input;
20219   vl_api_flow_classify_set_interface_t *mp;
20220   u32 sw_if_index;
20221   int sw_if_index_set;
20222   u32 ip4_table_index = ~0;
20223   u32 ip6_table_index = ~0;
20224   u8 is_add = 1;
20225   int ret;
20226
20227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20228     {
20229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20230         sw_if_index_set = 1;
20231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20232         sw_if_index_set = 1;
20233       else if (unformat (i, "del"))
20234         is_add = 0;
20235       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20236         ;
20237       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20238         ;
20239       else
20240         {
20241           clib_warning ("parse error '%U'", format_unformat_error, i);
20242           return -99;
20243         }
20244     }
20245
20246   if (sw_if_index_set == 0)
20247     {
20248       errmsg ("missing interface name or sw_if_index");
20249       return -99;
20250     }
20251
20252   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20253
20254   mp->sw_if_index = ntohl (sw_if_index);
20255   mp->ip4_table_index = ntohl (ip4_table_index);
20256   mp->ip6_table_index = ntohl (ip6_table_index);
20257   mp->is_add = is_add;
20258
20259   S (mp);
20260   W (ret);
20261   return ret;
20262 }
20263
20264 static int
20265 api_flow_classify_dump (vat_main_t * vam)
20266 {
20267   unformat_input_t *i = vam->input;
20268   vl_api_flow_classify_dump_t *mp;
20269   vl_api_control_ping_t *mp_ping;
20270   u8 type = FLOW_CLASSIFY_N_TABLES;
20271   int ret;
20272
20273   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20274     ;
20275   else
20276     {
20277       errmsg ("classify table type must be specified");
20278       return -99;
20279     }
20280
20281   if (!vam->json_output)
20282     {
20283       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20284     }
20285
20286   M (FLOW_CLASSIFY_DUMP, mp);
20287   mp->type = type;
20288   /* send it... */
20289   S (mp);
20290
20291   /* Use a control ping for synchronization */
20292   MPING (CONTROL_PING, mp_ping);
20293   S (mp_ping);
20294
20295   /* Wait for a reply... */
20296   W (ret);
20297   return ret;
20298 }
20299
20300 static int
20301 api_feature_enable_disable (vat_main_t * vam)
20302 {
20303   unformat_input_t *i = vam->input;
20304   vl_api_feature_enable_disable_t *mp;
20305   u8 *arc_name = 0;
20306   u8 *feature_name = 0;
20307   u32 sw_if_index = ~0;
20308   u8 enable = 1;
20309   int ret;
20310
20311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20312     {
20313       if (unformat (i, "arc_name %s", &arc_name))
20314         ;
20315       else if (unformat (i, "feature_name %s", &feature_name))
20316         ;
20317       else
20318         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20319         ;
20320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20321         ;
20322       else if (unformat (i, "disable"))
20323         enable = 0;
20324       else
20325         break;
20326     }
20327
20328   if (arc_name == 0)
20329     {
20330       errmsg ("missing arc name");
20331       return -99;
20332     }
20333   if (vec_len (arc_name) > 63)
20334     {
20335       errmsg ("arc name too long");
20336     }
20337
20338   if (feature_name == 0)
20339     {
20340       errmsg ("missing feature name");
20341       return -99;
20342     }
20343   if (vec_len (feature_name) > 63)
20344     {
20345       errmsg ("feature name too long");
20346     }
20347
20348   if (sw_if_index == ~0)
20349     {
20350       errmsg ("missing interface name or sw_if_index");
20351       return -99;
20352     }
20353
20354   /* Construct the API message */
20355   M (FEATURE_ENABLE_DISABLE, mp);
20356   mp->sw_if_index = ntohl (sw_if_index);
20357   mp->enable = enable;
20358   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20359   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20360   vec_free (arc_name);
20361   vec_free (feature_name);
20362
20363   S (mp);
20364   W (ret);
20365   return ret;
20366 }
20367
20368 static int
20369 api_sw_interface_tag_add_del (vat_main_t * vam)
20370 {
20371   unformat_input_t *i = vam->input;
20372   vl_api_sw_interface_tag_add_del_t *mp;
20373   u32 sw_if_index = ~0;
20374   u8 *tag = 0;
20375   u8 enable = 1;
20376   int ret;
20377
20378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20379     {
20380       if (unformat (i, "tag %s", &tag))
20381         ;
20382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20383         ;
20384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20385         ;
20386       else if (unformat (i, "del"))
20387         enable = 0;
20388       else
20389         break;
20390     }
20391
20392   if (sw_if_index == ~0)
20393     {
20394       errmsg ("missing interface name or sw_if_index");
20395       return -99;
20396     }
20397
20398   if (enable && (tag == 0))
20399     {
20400       errmsg ("no tag specified");
20401       return -99;
20402     }
20403
20404   /* Construct the API message */
20405   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20406   mp->sw_if_index = ntohl (sw_if_index);
20407   mp->is_add = enable;
20408   if (enable)
20409     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20410   vec_free (tag);
20411
20412   S (mp);
20413   W (ret);
20414   return ret;
20415 }
20416
20417 static void vl_api_l2_xconnect_details_t_handler
20418   (vl_api_l2_xconnect_details_t * mp)
20419 {
20420   vat_main_t *vam = &vat_main;
20421
20422   print (vam->ofp, "%15d%15d",
20423          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20424 }
20425
20426 static void vl_api_l2_xconnect_details_t_handler_json
20427   (vl_api_l2_xconnect_details_t * mp)
20428 {
20429   vat_main_t *vam = &vat_main;
20430   vat_json_node_t *node = NULL;
20431
20432   if (VAT_JSON_ARRAY != vam->json_tree.type)
20433     {
20434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20435       vat_json_init_array (&vam->json_tree);
20436     }
20437   node = vat_json_array_add (&vam->json_tree);
20438
20439   vat_json_init_object (node);
20440   vat_json_object_add_uint (node, "rx_sw_if_index",
20441                             ntohl (mp->rx_sw_if_index));
20442   vat_json_object_add_uint (node, "tx_sw_if_index",
20443                             ntohl (mp->tx_sw_if_index));
20444 }
20445
20446 static int
20447 api_l2_xconnect_dump (vat_main_t * vam)
20448 {
20449   vl_api_l2_xconnect_dump_t *mp;
20450   vl_api_control_ping_t *mp_ping;
20451   int ret;
20452
20453   if (!vam->json_output)
20454     {
20455       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20456     }
20457
20458   M (L2_XCONNECT_DUMP, mp);
20459
20460   S (mp);
20461
20462   /* Use a control ping for synchronization */
20463   MPING (CONTROL_PING, mp_ping);
20464   S (mp_ping);
20465
20466   W (ret);
20467   return ret;
20468 }
20469
20470 static int
20471 api_hw_interface_set_mtu (vat_main_t * vam)
20472 {
20473   unformat_input_t *i = vam->input;
20474   vl_api_hw_interface_set_mtu_t *mp;
20475   u32 sw_if_index = ~0;
20476   u32 mtu = 0;
20477   int ret;
20478
20479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20480     {
20481       if (unformat (i, "mtu %d", &mtu))
20482         ;
20483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20484         ;
20485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20486         ;
20487       else
20488         break;
20489     }
20490
20491   if (sw_if_index == ~0)
20492     {
20493       errmsg ("missing interface name or sw_if_index");
20494       return -99;
20495     }
20496
20497   if (mtu == 0)
20498     {
20499       errmsg ("no mtu specified");
20500       return -99;
20501     }
20502
20503   /* Construct the API message */
20504   M (HW_INTERFACE_SET_MTU, mp);
20505   mp->sw_if_index = ntohl (sw_if_index);
20506   mp->mtu = ntohs ((u16) mtu);
20507
20508   S (mp);
20509   W (ret);
20510   return ret;
20511 }
20512
20513 static int
20514 api_p2p_ethernet_add (vat_main_t * vam)
20515 {
20516   unformat_input_t *i = vam->input;
20517   vl_api_p2p_ethernet_add_t *mp;
20518   u32 parent_if_index = ~0;
20519   u32 sub_id = ~0;
20520   u8 remote_mac[6];
20521   u8 mac_set = 0;
20522   int ret;
20523
20524   clib_memset (remote_mac, 0, sizeof (remote_mac));
20525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20526     {
20527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20528         ;
20529       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20530         ;
20531       else
20532         if (unformat
20533             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20534         mac_set++;
20535       else if (unformat (i, "sub_id %d", &sub_id))
20536         ;
20537       else
20538         {
20539           clib_warning ("parse error '%U'", format_unformat_error, i);
20540           return -99;
20541         }
20542     }
20543
20544   if (parent_if_index == ~0)
20545     {
20546       errmsg ("missing interface name or sw_if_index");
20547       return -99;
20548     }
20549   if (mac_set == 0)
20550     {
20551       errmsg ("missing remote mac address");
20552       return -99;
20553     }
20554   if (sub_id == ~0)
20555     {
20556       errmsg ("missing sub-interface id");
20557       return -99;
20558     }
20559
20560   M (P2P_ETHERNET_ADD, mp);
20561   mp->parent_if_index = ntohl (parent_if_index);
20562   mp->subif_id = ntohl (sub_id);
20563   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20564
20565   S (mp);
20566   W (ret);
20567   return ret;
20568 }
20569
20570 static int
20571 api_p2p_ethernet_del (vat_main_t * vam)
20572 {
20573   unformat_input_t *i = vam->input;
20574   vl_api_p2p_ethernet_del_t *mp;
20575   u32 parent_if_index = ~0;
20576   u8 remote_mac[6];
20577   u8 mac_set = 0;
20578   int ret;
20579
20580   clib_memset (remote_mac, 0, sizeof (remote_mac));
20581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20582     {
20583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20584         ;
20585       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20586         ;
20587       else
20588         if (unformat
20589             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20590         mac_set++;
20591       else
20592         {
20593           clib_warning ("parse error '%U'", format_unformat_error, i);
20594           return -99;
20595         }
20596     }
20597
20598   if (parent_if_index == ~0)
20599     {
20600       errmsg ("missing interface name or sw_if_index");
20601       return -99;
20602     }
20603   if (mac_set == 0)
20604     {
20605       errmsg ("missing remote mac address");
20606       return -99;
20607     }
20608
20609   M (P2P_ETHERNET_DEL, mp);
20610   mp->parent_if_index = ntohl (parent_if_index);
20611   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20612
20613   S (mp);
20614   W (ret);
20615   return ret;
20616 }
20617
20618 static int
20619 api_lldp_config (vat_main_t * vam)
20620 {
20621   unformat_input_t *i = vam->input;
20622   vl_api_lldp_config_t *mp;
20623   int tx_hold = 0;
20624   int tx_interval = 0;
20625   u8 *sys_name = NULL;
20626   int ret;
20627
20628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20629     {
20630       if (unformat (i, "system-name %s", &sys_name))
20631         ;
20632       else if (unformat (i, "tx-hold %d", &tx_hold))
20633         ;
20634       else if (unformat (i, "tx-interval %d", &tx_interval))
20635         ;
20636       else
20637         {
20638           clib_warning ("parse error '%U'", format_unformat_error, i);
20639           return -99;
20640         }
20641     }
20642
20643   vec_add1 (sys_name, 0);
20644
20645   M (LLDP_CONFIG, mp);
20646   mp->tx_hold = htonl (tx_hold);
20647   mp->tx_interval = htonl (tx_interval);
20648   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20649   vec_free (sys_name);
20650
20651   S (mp);
20652   W (ret);
20653   return ret;
20654 }
20655
20656 static int
20657 api_sw_interface_set_lldp (vat_main_t * vam)
20658 {
20659   unformat_input_t *i = vam->input;
20660   vl_api_sw_interface_set_lldp_t *mp;
20661   u32 sw_if_index = ~0;
20662   u32 enable = 1;
20663   u8 *port_desc = NULL, *mgmt_oid = NULL;
20664   ip4_address_t ip4_addr;
20665   ip6_address_t ip6_addr;
20666   int ret;
20667
20668   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20669   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20670
20671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20672     {
20673       if (unformat (i, "disable"))
20674         enable = 0;
20675       else
20676         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20677         ;
20678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20679         ;
20680       else if (unformat (i, "port-desc %s", &port_desc))
20681         ;
20682       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20683         ;
20684       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20685         ;
20686       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20687         ;
20688       else
20689         break;
20690     }
20691
20692   if (sw_if_index == ~0)
20693     {
20694       errmsg ("missing interface name or sw_if_index");
20695       return -99;
20696     }
20697
20698   /* Construct the API message */
20699   vec_add1 (port_desc, 0);
20700   vec_add1 (mgmt_oid, 0);
20701   M (SW_INTERFACE_SET_LLDP, mp);
20702   mp->sw_if_index = ntohl (sw_if_index);
20703   mp->enable = enable;
20704   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20705   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20706   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20707   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20708   vec_free (port_desc);
20709   vec_free (mgmt_oid);
20710
20711   S (mp);
20712   W (ret);
20713   return ret;
20714 }
20715
20716 static int
20717 api_tcp_configure_src_addresses (vat_main_t * vam)
20718 {
20719   vl_api_tcp_configure_src_addresses_t *mp;
20720   unformat_input_t *i = vam->input;
20721   ip4_address_t v4first, v4last;
20722   ip6_address_t v6first, v6last;
20723   u8 range_set = 0;
20724   u32 vrf_id = 0;
20725   int ret;
20726
20727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20728     {
20729       if (unformat (i, "%U - %U",
20730                     unformat_ip4_address, &v4first,
20731                     unformat_ip4_address, &v4last))
20732         {
20733           if (range_set)
20734             {
20735               errmsg ("one range per message (range already set)");
20736               return -99;
20737             }
20738           range_set = 1;
20739         }
20740       else if (unformat (i, "%U - %U",
20741                          unformat_ip6_address, &v6first,
20742                          unformat_ip6_address, &v6last))
20743         {
20744           if (range_set)
20745             {
20746               errmsg ("one range per message (range already set)");
20747               return -99;
20748             }
20749           range_set = 2;
20750         }
20751       else if (unformat (i, "vrf %d", &vrf_id))
20752         ;
20753       else
20754         break;
20755     }
20756
20757   if (range_set == 0)
20758     {
20759       errmsg ("address range not set");
20760       return -99;
20761     }
20762
20763   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20764   mp->vrf_id = ntohl (vrf_id);
20765   /* ipv6? */
20766   if (range_set == 2)
20767     {
20768       mp->is_ipv6 = 1;
20769       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20770       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20771     }
20772   else
20773     {
20774       mp->is_ipv6 = 0;
20775       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20776       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20777     }
20778   S (mp);
20779   W (ret);
20780   return ret;
20781 }
20782
20783 static void vl_api_app_namespace_add_del_reply_t_handler
20784   (vl_api_app_namespace_add_del_reply_t * mp)
20785 {
20786   vat_main_t *vam = &vat_main;
20787   i32 retval = ntohl (mp->retval);
20788   if (vam->async_mode)
20789     {
20790       vam->async_errors += (retval < 0);
20791     }
20792   else
20793     {
20794       vam->retval = retval;
20795       if (retval == 0)
20796         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20797       vam->result_ready = 1;
20798     }
20799 }
20800
20801 static void vl_api_app_namespace_add_del_reply_t_handler_json
20802   (vl_api_app_namespace_add_del_reply_t * mp)
20803 {
20804   vat_main_t *vam = &vat_main;
20805   vat_json_node_t node;
20806
20807   vat_json_init_object (&node);
20808   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20809   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20810
20811   vat_json_print (vam->ofp, &node);
20812   vat_json_free (&node);
20813
20814   vam->retval = ntohl (mp->retval);
20815   vam->result_ready = 1;
20816 }
20817
20818 static int
20819 api_app_namespace_add_del (vat_main_t * vam)
20820 {
20821   vl_api_app_namespace_add_del_t *mp;
20822   unformat_input_t *i = vam->input;
20823   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20824   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20825   u64 secret;
20826   int ret;
20827
20828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20829     {
20830       if (unformat (i, "id %_%v%_", &ns_id))
20831         ;
20832       else if (unformat (i, "secret %lu", &secret))
20833         secret_set = 1;
20834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20835         sw_if_index_set = 1;
20836       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20837         ;
20838       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20839         ;
20840       else
20841         break;
20842     }
20843   if (!ns_id || !secret_set || !sw_if_index_set)
20844     {
20845       errmsg ("namespace id, secret and sw_if_index must be set");
20846       return -99;
20847     }
20848   if (vec_len (ns_id) > 64)
20849     {
20850       errmsg ("namespace id too long");
20851       return -99;
20852     }
20853   M (APP_NAMESPACE_ADD_DEL, mp);
20854
20855   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20856   mp->namespace_id_len = vec_len (ns_id);
20857   mp->secret = clib_host_to_net_u64 (secret);
20858   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20859   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20860   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20861   vec_free (ns_id);
20862   S (mp);
20863   W (ret);
20864   return ret;
20865 }
20866
20867 static int
20868 api_sock_init_shm (vat_main_t * vam)
20869 {
20870 #if VPP_API_TEST_BUILTIN == 0
20871   unformat_input_t *i = vam->input;
20872   vl_api_shm_elem_config_t *config = 0;
20873   u64 size = 64 << 20;
20874   int rv;
20875
20876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20877     {
20878       if (unformat (i, "size %U", unformat_memory_size, &size))
20879         ;
20880       else
20881         break;
20882     }
20883
20884   /*
20885    * Canned custom ring allocator config.
20886    * Should probably parse all of this
20887    */
20888   vec_validate (config, 6);
20889   config[0].type = VL_API_VLIB_RING;
20890   config[0].size = 256;
20891   config[0].count = 32;
20892
20893   config[1].type = VL_API_VLIB_RING;
20894   config[1].size = 1024;
20895   config[1].count = 16;
20896
20897   config[2].type = VL_API_VLIB_RING;
20898   config[2].size = 4096;
20899   config[2].count = 2;
20900
20901   config[3].type = VL_API_CLIENT_RING;
20902   config[3].size = 256;
20903   config[3].count = 32;
20904
20905   config[4].type = VL_API_CLIENT_RING;
20906   config[4].size = 1024;
20907   config[4].count = 16;
20908
20909   config[5].type = VL_API_CLIENT_RING;
20910   config[5].size = 4096;
20911   config[5].count = 2;
20912
20913   config[6].type = VL_API_QUEUE;
20914   config[6].count = 128;
20915   config[6].size = sizeof (uword);
20916
20917   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20918   if (!rv)
20919     vam->client_index_invalid = 1;
20920   return rv;
20921 #else
20922   return -99;
20923 #endif
20924 }
20925
20926 static int
20927 api_dns_enable_disable (vat_main_t * vam)
20928 {
20929   unformat_input_t *line_input = vam->input;
20930   vl_api_dns_enable_disable_t *mp;
20931   u8 enable_disable = 1;
20932   int ret;
20933
20934   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20935     {
20936       if (unformat (line_input, "disable"))
20937         enable_disable = 0;
20938       if (unformat (line_input, "enable"))
20939         enable_disable = 1;
20940       else
20941         break;
20942     }
20943
20944   /* Construct the API message */
20945   M (DNS_ENABLE_DISABLE, mp);
20946   mp->enable = enable_disable;
20947
20948   /* send it... */
20949   S (mp);
20950   /* Wait for the reply */
20951   W (ret);
20952   return ret;
20953 }
20954
20955 static int
20956 api_dns_resolve_name (vat_main_t * vam)
20957 {
20958   unformat_input_t *line_input = vam->input;
20959   vl_api_dns_resolve_name_t *mp;
20960   u8 *name = 0;
20961   int ret;
20962
20963   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20964     {
20965       if (unformat (line_input, "%s", &name))
20966         ;
20967       else
20968         break;
20969     }
20970
20971   if (vec_len (name) > 127)
20972     {
20973       errmsg ("name too long");
20974       return -99;
20975     }
20976
20977   /* Construct the API message */
20978   M (DNS_RESOLVE_NAME, mp);
20979   memcpy (mp->name, name, vec_len (name));
20980   vec_free (name);
20981
20982   /* send it... */
20983   S (mp);
20984   /* Wait for the reply */
20985   W (ret);
20986   return ret;
20987 }
20988
20989 static int
20990 api_dns_resolve_ip (vat_main_t * vam)
20991 {
20992   unformat_input_t *line_input = vam->input;
20993   vl_api_dns_resolve_ip_t *mp;
20994   int is_ip6 = -1;
20995   ip4_address_t addr4;
20996   ip6_address_t addr6;
20997   int ret;
20998
20999   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21000     {
21001       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21002         is_ip6 = 1;
21003       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21004         is_ip6 = 0;
21005       else
21006         break;
21007     }
21008
21009   if (is_ip6 == -1)
21010     {
21011       errmsg ("missing address");
21012       return -99;
21013     }
21014
21015   /* Construct the API message */
21016   M (DNS_RESOLVE_IP, mp);
21017   mp->is_ip6 = is_ip6;
21018   if (is_ip6)
21019     memcpy (mp->address, &addr6, sizeof (addr6));
21020   else
21021     memcpy (mp->address, &addr4, sizeof (addr4));
21022
21023   /* send it... */
21024   S (mp);
21025   /* Wait for the reply */
21026   W (ret);
21027   return ret;
21028 }
21029
21030 static int
21031 api_dns_name_server_add_del (vat_main_t * vam)
21032 {
21033   unformat_input_t *i = vam->input;
21034   vl_api_dns_name_server_add_del_t *mp;
21035   u8 is_add = 1;
21036   ip6_address_t ip6_server;
21037   ip4_address_t ip4_server;
21038   int ip6_set = 0;
21039   int ip4_set = 0;
21040   int ret = 0;
21041
21042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21043     {
21044       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21045         ip6_set = 1;
21046       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21047         ip4_set = 1;
21048       else if (unformat (i, "del"))
21049         is_add = 0;
21050       else
21051         {
21052           clib_warning ("parse error '%U'", format_unformat_error, i);
21053           return -99;
21054         }
21055     }
21056
21057   if (ip4_set && ip6_set)
21058     {
21059       errmsg ("Only one server address allowed per message");
21060       return -99;
21061     }
21062   if ((ip4_set + ip6_set) == 0)
21063     {
21064       errmsg ("Server address required");
21065       return -99;
21066     }
21067
21068   /* Construct the API message */
21069   M (DNS_NAME_SERVER_ADD_DEL, mp);
21070
21071   if (ip6_set)
21072     {
21073       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21074       mp->is_ip6 = 1;
21075     }
21076   else
21077     {
21078       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21079       mp->is_ip6 = 0;
21080     }
21081
21082   mp->is_add = is_add;
21083
21084   /* send it... */
21085   S (mp);
21086
21087   /* Wait for a reply, return good/bad news  */
21088   W (ret);
21089   return ret;
21090 }
21091
21092 static void
21093 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21094 {
21095   vat_main_t *vam = &vat_main;
21096
21097   if (mp->is_ip4)
21098     {
21099       print (vam->ofp,
21100              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21101              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21102              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21103              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21104              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21105              clib_net_to_host_u32 (mp->action_index), mp->tag);
21106     }
21107   else
21108     {
21109       print (vam->ofp,
21110              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21111              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21112              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21113              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21114              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21115              clib_net_to_host_u32 (mp->action_index), mp->tag);
21116     }
21117 }
21118
21119 static void
21120 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21121                                              mp)
21122 {
21123   vat_main_t *vam = &vat_main;
21124   vat_json_node_t *node = NULL;
21125   struct in6_addr ip6;
21126   struct in_addr ip4;
21127
21128   if (VAT_JSON_ARRAY != vam->json_tree.type)
21129     {
21130       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21131       vat_json_init_array (&vam->json_tree);
21132     }
21133   node = vat_json_array_add (&vam->json_tree);
21134   vat_json_init_object (node);
21135
21136   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21137   vat_json_object_add_uint (node, "appns_index",
21138                             clib_net_to_host_u32 (mp->appns_index));
21139   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21140   vat_json_object_add_uint (node, "scope", mp->scope);
21141   vat_json_object_add_uint (node, "action_index",
21142                             clib_net_to_host_u32 (mp->action_index));
21143   vat_json_object_add_uint (node, "lcl_port",
21144                             clib_net_to_host_u16 (mp->lcl_port));
21145   vat_json_object_add_uint (node, "rmt_port",
21146                             clib_net_to_host_u16 (mp->rmt_port));
21147   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21148   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21149   vat_json_object_add_string_copy (node, "tag", mp->tag);
21150   if (mp->is_ip4)
21151     {
21152       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21153       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21154       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21155       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21156     }
21157   else
21158     {
21159       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21160       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21161       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21162       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21163     }
21164 }
21165
21166 static int
21167 api_session_rule_add_del (vat_main_t * vam)
21168 {
21169   vl_api_session_rule_add_del_t *mp;
21170   unformat_input_t *i = vam->input;
21171   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21172   u32 appns_index = 0, scope = 0;
21173   ip4_address_t lcl_ip4, rmt_ip4;
21174   ip6_address_t lcl_ip6, rmt_ip6;
21175   u8 is_ip4 = 1, conn_set = 0;
21176   u8 is_add = 1, *tag = 0;
21177   int ret;
21178
21179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21180     {
21181       if (unformat (i, "del"))
21182         is_add = 0;
21183       else if (unformat (i, "add"))
21184         ;
21185       else if (unformat (i, "proto tcp"))
21186         proto = 0;
21187       else if (unformat (i, "proto udp"))
21188         proto = 1;
21189       else if (unformat (i, "appns %d", &appns_index))
21190         ;
21191       else if (unformat (i, "scope %d", &scope))
21192         ;
21193       else if (unformat (i, "tag %_%v%_", &tag))
21194         ;
21195       else
21196         if (unformat
21197             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21198              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21199              &rmt_port))
21200         {
21201           is_ip4 = 1;
21202           conn_set = 1;
21203         }
21204       else
21205         if (unformat
21206             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21207              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21208              &rmt_port))
21209         {
21210           is_ip4 = 0;
21211           conn_set = 1;
21212         }
21213       else if (unformat (i, "action %d", &action))
21214         ;
21215       else
21216         break;
21217     }
21218   if (proto == ~0 || !conn_set || action == ~0)
21219     {
21220       errmsg ("transport proto, connection and action must be set");
21221       return -99;
21222     }
21223
21224   if (scope > 3)
21225     {
21226       errmsg ("scope should be 0-3");
21227       return -99;
21228     }
21229
21230   M (SESSION_RULE_ADD_DEL, mp);
21231
21232   mp->is_ip4 = is_ip4;
21233   mp->transport_proto = proto;
21234   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21235   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21236   mp->lcl_plen = lcl_plen;
21237   mp->rmt_plen = rmt_plen;
21238   mp->action_index = clib_host_to_net_u32 (action);
21239   mp->appns_index = clib_host_to_net_u32 (appns_index);
21240   mp->scope = scope;
21241   mp->is_add = is_add;
21242   if (is_ip4)
21243     {
21244       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21245       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21246     }
21247   else
21248     {
21249       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21250       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21251     }
21252   if (tag)
21253     {
21254       clib_memcpy (mp->tag, tag, vec_len (tag));
21255       vec_free (tag);
21256     }
21257
21258   S (mp);
21259   W (ret);
21260   return ret;
21261 }
21262
21263 static int
21264 api_session_rules_dump (vat_main_t * vam)
21265 {
21266   vl_api_session_rules_dump_t *mp;
21267   vl_api_control_ping_t *mp_ping;
21268   int ret;
21269
21270   if (!vam->json_output)
21271     {
21272       print (vam->ofp, "%=20s", "Session Rules");
21273     }
21274
21275   M (SESSION_RULES_DUMP, mp);
21276   /* send it... */
21277   S (mp);
21278
21279   /* Use a control ping for synchronization */
21280   MPING (CONTROL_PING, mp_ping);
21281   S (mp_ping);
21282
21283   /* Wait for a reply... */
21284   W (ret);
21285   return ret;
21286 }
21287
21288 static int
21289 api_ip_container_proxy_add_del (vat_main_t * vam)
21290 {
21291   vl_api_ip_container_proxy_add_del_t *mp;
21292   unformat_input_t *i = vam->input;
21293   u32 sw_if_index = ~0;
21294   vl_api_prefix_t pfx = { };
21295   u8 is_add = 1;
21296   int ret;
21297
21298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21299     {
21300       if (unformat (i, "del"))
21301         is_add = 0;
21302       else if (unformat (i, "add"))
21303         ;
21304       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21305         ;
21306       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21307         ;
21308       else
21309         break;
21310     }
21311   if (sw_if_index == ~0 || pfx.len == 0)
21312     {
21313       errmsg ("address and sw_if_index must be set");
21314       return -99;
21315     }
21316
21317   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21318
21319   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21320   mp->is_add = is_add;
21321   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21322
21323   S (mp);
21324   W (ret);
21325   return ret;
21326 }
21327
21328 static int
21329 api_qos_record_enable_disable (vat_main_t * vam)
21330 {
21331   unformat_input_t *i = vam->input;
21332   vl_api_qos_record_enable_disable_t *mp;
21333   u32 sw_if_index, qs = 0xff;
21334   u8 sw_if_index_set = 0;
21335   u8 enable = 1;
21336   int ret;
21337
21338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21339     {
21340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21341         sw_if_index_set = 1;
21342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21343         sw_if_index_set = 1;
21344       else if (unformat (i, "%U", unformat_qos_source, &qs))
21345         ;
21346       else if (unformat (i, "disable"))
21347         enable = 0;
21348       else
21349         {
21350           clib_warning ("parse error '%U'", format_unformat_error, i);
21351           return -99;
21352         }
21353     }
21354
21355   if (sw_if_index_set == 0)
21356     {
21357       errmsg ("missing interface name or sw_if_index");
21358       return -99;
21359     }
21360   if (qs == 0xff)
21361     {
21362       errmsg ("input location must be specified");
21363       return -99;
21364     }
21365
21366   M (QOS_RECORD_ENABLE_DISABLE, mp);
21367
21368   mp->sw_if_index = ntohl (sw_if_index);
21369   mp->input_source = qs;
21370   mp->enable = enable;
21371
21372   S (mp);
21373   W (ret);
21374   return ret;
21375 }
21376
21377
21378 static int
21379 q_or_quit (vat_main_t * vam)
21380 {
21381 #if VPP_API_TEST_BUILTIN == 0
21382   longjmp (vam->jump_buf, 1);
21383 #endif
21384   return 0;                     /* not so much */
21385 }
21386
21387 static int
21388 q (vat_main_t * vam)
21389 {
21390   return q_or_quit (vam);
21391 }
21392
21393 static int
21394 quit (vat_main_t * vam)
21395 {
21396   return q_or_quit (vam);
21397 }
21398
21399 static int
21400 comment (vat_main_t * vam)
21401 {
21402   return 0;
21403 }
21404
21405 static int
21406 statseg (vat_main_t * vam)
21407 {
21408   ssvm_private_t *ssvmp = &vam->stat_segment;
21409   ssvm_shared_header_t *shared_header = ssvmp->sh;
21410   vlib_counter_t **counters;
21411   u64 thread0_index1_packets;
21412   u64 thread0_index1_bytes;
21413   f64 vector_rate, input_rate;
21414   uword *p;
21415
21416   uword *counter_vector_by_name;
21417   if (vam->stat_segment_lockp == 0)
21418     {
21419       errmsg ("Stat segment not mapped...");
21420       return -99;
21421     }
21422
21423   /* look up "/if/rx for sw_if_index 1 as a test */
21424
21425   clib_spinlock_lock (vam->stat_segment_lockp);
21426
21427   counter_vector_by_name = (uword *) shared_header->opaque[1];
21428
21429   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21430   if (p == 0)
21431     {
21432       clib_spinlock_unlock (vam->stat_segment_lockp);
21433       errmsg ("/if/tx not found?");
21434       return -99;
21435     }
21436
21437   /* Fish per-thread vector of combined counters from shared memory */
21438   counters = (vlib_counter_t **) p[0];
21439
21440   if (vec_len (counters[0]) < 2)
21441     {
21442       clib_spinlock_unlock (vam->stat_segment_lockp);
21443       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21444       return -99;
21445     }
21446
21447   /* Read thread 0 sw_if_index 1 counter */
21448   thread0_index1_packets = counters[0][1].packets;
21449   thread0_index1_bytes = counters[0][1].bytes;
21450
21451   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21452   if (p == 0)
21453     {
21454       clib_spinlock_unlock (vam->stat_segment_lockp);
21455       errmsg ("vector_rate not found?");
21456       return -99;
21457     }
21458
21459   vector_rate = *(f64 *) (p[0]);
21460   p = hash_get_mem (counter_vector_by_name, "input_rate");
21461   if (p == 0)
21462     {
21463       clib_spinlock_unlock (vam->stat_segment_lockp);
21464       errmsg ("input_rate not found?");
21465       return -99;
21466     }
21467   input_rate = *(f64 *) (p[0]);
21468
21469   clib_spinlock_unlock (vam->stat_segment_lockp);
21470
21471   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21472          vector_rate, input_rate);
21473   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21474          thread0_index1_packets, thread0_index1_bytes);
21475
21476   return 0;
21477 }
21478
21479 static int
21480 cmd_cmp (void *a1, void *a2)
21481 {
21482   u8 **c1 = a1;
21483   u8 **c2 = a2;
21484
21485   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21486 }
21487
21488 static int
21489 help (vat_main_t * vam)
21490 {
21491   u8 **cmds = 0;
21492   u8 *name = 0;
21493   hash_pair_t *p;
21494   unformat_input_t *i = vam->input;
21495   int j;
21496
21497   if (unformat (i, "%s", &name))
21498     {
21499       uword *hs;
21500
21501       vec_add1 (name, 0);
21502
21503       hs = hash_get_mem (vam->help_by_name, name);
21504       if (hs)
21505         print (vam->ofp, "usage: %s %s", name, hs[0]);
21506       else
21507         print (vam->ofp, "No such msg / command '%s'", name);
21508       vec_free (name);
21509       return 0;
21510     }
21511
21512   print (vam->ofp, "Help is available for the following:");
21513
21514     /* *INDENT-OFF* */
21515     hash_foreach_pair (p, vam->function_by_name,
21516     ({
21517       vec_add1 (cmds, (u8 *)(p->key));
21518     }));
21519     /* *INDENT-ON* */
21520
21521   vec_sort_with_function (cmds, cmd_cmp);
21522
21523   for (j = 0; j < vec_len (cmds); j++)
21524     print (vam->ofp, "%s", cmds[j]);
21525
21526   vec_free (cmds);
21527   return 0;
21528 }
21529
21530 static int
21531 set (vat_main_t * vam)
21532 {
21533   u8 *name = 0, *value = 0;
21534   unformat_input_t *i = vam->input;
21535
21536   if (unformat (i, "%s", &name))
21537     {
21538       /* The input buffer is a vector, not a string. */
21539       value = vec_dup (i->buffer);
21540       vec_delete (value, i->index, 0);
21541       /* Almost certainly has a trailing newline */
21542       if (value[vec_len (value) - 1] == '\n')
21543         value[vec_len (value) - 1] = 0;
21544       /* Make sure it's a proper string, one way or the other */
21545       vec_add1 (value, 0);
21546       (void) clib_macro_set_value (&vam->macro_main,
21547                                    (char *) name, (char *) value);
21548     }
21549   else
21550     errmsg ("usage: set <name> <value>");
21551
21552   vec_free (name);
21553   vec_free (value);
21554   return 0;
21555 }
21556
21557 static int
21558 unset (vat_main_t * vam)
21559 {
21560   u8 *name = 0;
21561
21562   if (unformat (vam->input, "%s", &name))
21563     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21564       errmsg ("unset: %s wasn't set", name);
21565   vec_free (name);
21566   return 0;
21567 }
21568
21569 typedef struct
21570 {
21571   u8 *name;
21572   u8 *value;
21573 } macro_sort_t;
21574
21575
21576 static int
21577 macro_sort_cmp (void *a1, void *a2)
21578 {
21579   macro_sort_t *s1 = a1;
21580   macro_sort_t *s2 = a2;
21581
21582   return strcmp ((char *) (s1->name), (char *) (s2->name));
21583 }
21584
21585 static int
21586 dump_macro_table (vat_main_t * vam)
21587 {
21588   macro_sort_t *sort_me = 0, *sm;
21589   int i;
21590   hash_pair_t *p;
21591
21592     /* *INDENT-OFF* */
21593     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21594     ({
21595       vec_add2 (sort_me, sm, 1);
21596       sm->name = (u8 *)(p->key);
21597       sm->value = (u8 *) (p->value[0]);
21598     }));
21599     /* *INDENT-ON* */
21600
21601   vec_sort_with_function (sort_me, macro_sort_cmp);
21602
21603   if (vec_len (sort_me))
21604     print (vam->ofp, "%-15s%s", "Name", "Value");
21605   else
21606     print (vam->ofp, "The macro table is empty...");
21607
21608   for (i = 0; i < vec_len (sort_me); i++)
21609     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21610   return 0;
21611 }
21612
21613 static int
21614 dump_node_table (vat_main_t * vam)
21615 {
21616   int i, j;
21617   vlib_node_t *node, *next_node;
21618
21619   if (vec_len (vam->graph_nodes) == 0)
21620     {
21621       print (vam->ofp, "Node table empty, issue get_node_graph...");
21622       return 0;
21623     }
21624
21625   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21626     {
21627       node = vam->graph_nodes[0][i];
21628       print (vam->ofp, "[%d] %s", i, node->name);
21629       for (j = 0; j < vec_len (node->next_nodes); j++)
21630         {
21631           if (node->next_nodes[j] != ~0)
21632             {
21633               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21634               print (vam->ofp, "  [%d] %s", j, next_node->name);
21635             }
21636         }
21637     }
21638   return 0;
21639 }
21640
21641 static int
21642 value_sort_cmp (void *a1, void *a2)
21643 {
21644   name_sort_t *n1 = a1;
21645   name_sort_t *n2 = a2;
21646
21647   if (n1->value < n2->value)
21648     return -1;
21649   if (n1->value > n2->value)
21650     return 1;
21651   return 0;
21652 }
21653
21654
21655 static int
21656 dump_msg_api_table (vat_main_t * vam)
21657 {
21658   api_main_t *am = &api_main;
21659   name_sort_t *nses = 0, *ns;
21660   hash_pair_t *hp;
21661   int i;
21662
21663   /* *INDENT-OFF* */
21664   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21665   ({
21666     vec_add2 (nses, ns, 1);
21667     ns->name = (u8 *)(hp->key);
21668     ns->value = (u32) hp->value[0];
21669   }));
21670   /* *INDENT-ON* */
21671
21672   vec_sort_with_function (nses, value_sort_cmp);
21673
21674   for (i = 0; i < vec_len (nses); i++)
21675     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21676   vec_free (nses);
21677   return 0;
21678 }
21679
21680 static int
21681 get_msg_id (vat_main_t * vam)
21682 {
21683   u8 *name_and_crc;
21684   u32 message_index;
21685
21686   if (unformat (vam->input, "%s", &name_and_crc))
21687     {
21688       message_index = vl_msg_api_get_msg_index (name_and_crc);
21689       if (message_index == ~0)
21690         {
21691           print (vam->ofp, " '%s' not found", name_and_crc);
21692           return 0;
21693         }
21694       print (vam->ofp, " '%s' has message index %d",
21695              name_and_crc, message_index);
21696       return 0;
21697     }
21698   errmsg ("name_and_crc required...");
21699   return 0;
21700 }
21701
21702 static int
21703 search_node_table (vat_main_t * vam)
21704 {
21705   unformat_input_t *line_input = vam->input;
21706   u8 *node_to_find;
21707   int j;
21708   vlib_node_t *node, *next_node;
21709   uword *p;
21710
21711   if (vam->graph_node_index_by_name == 0)
21712     {
21713       print (vam->ofp, "Node table empty, issue get_node_graph...");
21714       return 0;
21715     }
21716
21717   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21718     {
21719       if (unformat (line_input, "%s", &node_to_find))
21720         {
21721           vec_add1 (node_to_find, 0);
21722           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21723           if (p == 0)
21724             {
21725               print (vam->ofp, "%s not found...", node_to_find);
21726               goto out;
21727             }
21728           node = vam->graph_nodes[0][p[0]];
21729           print (vam->ofp, "[%d] %s", p[0], node->name);
21730           for (j = 0; j < vec_len (node->next_nodes); j++)
21731             {
21732               if (node->next_nodes[j] != ~0)
21733                 {
21734                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21735                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21736                 }
21737             }
21738         }
21739
21740       else
21741         {
21742           clib_warning ("parse error '%U'", format_unformat_error,
21743                         line_input);
21744           return -99;
21745         }
21746
21747     out:
21748       vec_free (node_to_find);
21749
21750     }
21751
21752   return 0;
21753 }
21754
21755
21756 static int
21757 script (vat_main_t * vam)
21758 {
21759 #if (VPP_API_TEST_BUILTIN==0)
21760   u8 *s = 0;
21761   char *save_current_file;
21762   unformat_input_t save_input;
21763   jmp_buf save_jump_buf;
21764   u32 save_line_number;
21765
21766   FILE *new_fp, *save_ifp;
21767
21768   if (unformat (vam->input, "%s", &s))
21769     {
21770       new_fp = fopen ((char *) s, "r");
21771       if (new_fp == 0)
21772         {
21773           errmsg ("Couldn't open script file %s", s);
21774           vec_free (s);
21775           return -99;
21776         }
21777     }
21778   else
21779     {
21780       errmsg ("Missing script name");
21781       return -99;
21782     }
21783
21784   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21785   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21786   save_ifp = vam->ifp;
21787   save_line_number = vam->input_line_number;
21788   save_current_file = (char *) vam->current_file;
21789
21790   vam->input_line_number = 0;
21791   vam->ifp = new_fp;
21792   vam->current_file = s;
21793   do_one_file (vam);
21794
21795   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21796   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21797   vam->ifp = save_ifp;
21798   vam->input_line_number = save_line_number;
21799   vam->current_file = (u8 *) save_current_file;
21800   vec_free (s);
21801
21802   return 0;
21803 #else
21804   clib_warning ("use the exec command...");
21805   return -99;
21806 #endif
21807 }
21808
21809 static int
21810 echo (vat_main_t * vam)
21811 {
21812   print (vam->ofp, "%v", vam->input->buffer);
21813   return 0;
21814 }
21815
21816 /* List of API message constructors, CLI names map to api_xxx */
21817 #define foreach_vpe_api_msg                                             \
21818 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21819 _(sw_interface_dump,"")                                                 \
21820 _(sw_interface_set_flags,                                               \
21821   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21822 _(sw_interface_add_del_address,                                         \
21823   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21824 _(sw_interface_set_rx_mode,                                             \
21825   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21826 _(sw_interface_set_rx_placement,                                        \
21827   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21828 _(sw_interface_rx_placement_dump,                                       \
21829   "[<intfc> | sw_if_index <id>]")                                         \
21830 _(sw_interface_set_table,                                               \
21831   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21832 _(sw_interface_set_mpls_enable,                                         \
21833   "<intfc> | sw_if_index [disable | dis]")                              \
21834 _(sw_interface_set_vpath,                                               \
21835   "<intfc> | sw_if_index <id> enable | disable")                        \
21836 _(sw_interface_set_vxlan_bypass,                                        \
21837   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21838 _(sw_interface_set_geneve_bypass,                                       \
21839   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21840 _(sw_interface_set_l2_xconnect,                                         \
21841   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21842   "enable | disable")                                                   \
21843 _(sw_interface_set_l2_bridge,                                           \
21844   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21845   "[shg <split-horizon-group>] [bvi]\n"                                 \
21846   "enable | disable")                                                   \
21847 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21848 _(bridge_domain_add_del,                                                \
21849   "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") \
21850 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21851 _(l2fib_add_del,                                                        \
21852   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21853 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21854 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21855 _(l2_flags,                                                             \
21856   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21857 _(bridge_flags,                                                         \
21858   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21859 _(tap_create_v2,                                                        \
21860   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21861 _(tap_delete_v2,                                                        \
21862   "<vpp-if-name> | sw_if_index <id>")                                   \
21863 _(sw_interface_tap_v2_dump, "")                                         \
21864 _(virtio_pci_create,                                                    \
21865   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21866 _(virtio_pci_delete,                                                    \
21867   "<vpp-if-name> | sw_if_index <id>")                                   \
21868 _(sw_interface_virtio_pci_dump, "")                                     \
21869 _(bond_create,                                                          \
21870   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21871   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21872   "[id <if-id>]")                                                       \
21873 _(bond_delete,                                                          \
21874   "<vpp-if-name> | sw_if_index <id>")                                   \
21875 _(bond_enslave,                                                         \
21876   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21877 _(bond_detach_slave,                                                    \
21878   "sw_if_index <n>")                                                    \
21879 _(sw_interface_bond_dump, "")                                           \
21880 _(sw_interface_slave_dump,                                              \
21881   "<vpp-if-name> | sw_if_index <id>")                                   \
21882 _(ip_table_add_del,                                                     \
21883   "table <n> [ipv6] [add | del]\n")                                     \
21884 _(ip_route_add_del,                                                     \
21885   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21886   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21887   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21888   "[multipath] [count <n>] [del]")                                      \
21889 _(ip_mroute_add_del,                                                    \
21890   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21891   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21892 _(mpls_table_add_del,                                                   \
21893   "table <n> [add | del]\n")                                            \
21894 _(mpls_route_add_del,                                                   \
21895   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21896   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21897   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21898   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21899   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21900   "[count <n>] [del]")                                                  \
21901 _(mpls_ip_bind_unbind,                                                  \
21902   "<label> <addr/len>")                                                 \
21903 _(mpls_tunnel_add_del,                                                  \
21904   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21905   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21906   "[l2-only]  [out-label <n>]")                                         \
21907 _(sr_mpls_policy_add,                                                   \
21908   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21909 _(sr_mpls_policy_del,                                                   \
21910   "bsid <id>")                                                          \
21911 _(bier_table_add_del,                                                   \
21912   "<label> <sub-domain> <set> <bsl> [del]")                             \
21913 _(bier_route_add_del,                                                   \
21914   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21915   "[<intfc> | sw_if_index <id>]"                                        \
21916   "[weight <n>] [del] [multipath]")                                     \
21917 _(proxy_arp_add_del,                                                    \
21918   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21919 _(proxy_arp_intfc_enable_disable,                                       \
21920   "<intfc> | sw_if_index <id> enable | disable")                        \
21921 _(sw_interface_set_unnumbered,                                          \
21922   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21923 _(ip_neighbor_add_del,                                                  \
21924   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21925   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21926 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21927 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21928   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21929   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21930   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21931 _(reset_fib, "vrf <n> [ipv6]")                                          \
21932 _(dhcp_proxy_config,                                                    \
21933   "svr <v46-address> src <v46-address>\n"                               \
21934    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21935 _(dhcp_proxy_set_vss,                                                   \
21936   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21937 _(dhcp_proxy_dump, "ip6")                                               \
21938 _(dhcp_client_config,                                                   \
21939   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21940 _(set_ip_flow_hash,                                                     \
21941   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21942 _(sw_interface_ip6_enable_disable,                                      \
21943   "<intfc> | sw_if_index <id> enable | disable")                        \
21944 _(ip6nd_proxy_add_del,                                                  \
21945   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21946 _(ip6nd_proxy_dump, "")                                                 \
21947 _(sw_interface_ip6nd_ra_prefix,                                         \
21948   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21949   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21950   "[nolink] [isno]")                                                    \
21951 _(sw_interface_ip6nd_ra_config,                                         \
21952   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21953   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21954   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21955 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21956 _(l2_patch_add_del,                                                     \
21957   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21958   "enable | disable")                                                   \
21959 _(sr_localsid_add_del,                                                  \
21960   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21961   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21962 _(classify_add_del_table,                                               \
21963   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21964   " [del] [del-chain] mask <mask-value>\n"                              \
21965   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21966   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21967 _(classify_add_del_session,                                             \
21968   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21969   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21970   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21971   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21972 _(classify_set_interface_ip_table,                                      \
21973   "<intfc> | sw_if_index <nn> table <nn>")                              \
21974 _(classify_set_interface_l2_tables,                                     \
21975   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21976   "  [other-table <nn>]")                                               \
21977 _(get_node_index, "node <node-name")                                    \
21978 _(add_node_next, "node <node-name> next <next-node-name>")              \
21979 _(l2tpv3_create_tunnel,                                                 \
21980   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21981   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21982   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21983 _(l2tpv3_set_tunnel_cookies,                                            \
21984   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21985   "[new_remote_cookie <nn>]\n")                                         \
21986 _(l2tpv3_interface_enable_disable,                                      \
21987   "<intfc> | sw_if_index <nn> enable | disable")                        \
21988 _(l2tpv3_set_lookup_key,                                                \
21989   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21990 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21991 _(vxlan_offload_rx,                                                     \
21992   "hw { <interface name> | hw_if_index <nn>} "                          \
21993   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21994 _(vxlan_add_del_tunnel,                                                 \
21995   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21996   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21997   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21998 _(geneve_add_del_tunnel,                                                \
21999   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22000   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22001   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22002 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22003 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22004 _(gre_tunnel_add_del,                                                   \
22005   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22006   "[teb | erspan <session-id>] [del]")                                  \
22007 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22008 _(l2_fib_clear_table, "")                                               \
22009 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22010 _(l2_interface_vlan_tag_rewrite,                                        \
22011   "<intfc> | sw_if_index <nn> \n"                                       \
22012   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22013   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22014 _(create_vhost_user_if,                                                 \
22015         "socket <filename> [server] [renumber <dev_instance>] "         \
22016         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22017         "[mac <mac_address>]")                                          \
22018 _(modify_vhost_user_if,                                                 \
22019         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22020         "[server] [renumber <dev_instance>]")                           \
22021 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22022 _(sw_interface_vhost_user_dump, "")                                     \
22023 _(show_version, "")                                                     \
22024 _(show_threads, "")                                                     \
22025 _(vxlan_gpe_add_del_tunnel,                                             \
22026   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22027   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22028   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22029   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22030 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22031 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22032 _(interface_name_renumber,                                              \
22033   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22034 _(input_acl_set_interface,                                              \
22035   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22036   "  [l2-table <nn>] [del]")                                            \
22037 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22038 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22039   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22040 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22041 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22042 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22043 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22044 _(ip_dump, "ipv4 | ipv6")                                               \
22045 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22046 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22047   "  spid_id <n> ")                                                     \
22048 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22049   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22050   "  integ_alg <alg> integ_key <hex>")                                  \
22051 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22052   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22053   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22054   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22055 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22056   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22057   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22058   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22059   "  [instance <n>]")     \
22060 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22061 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22062 _(delete_loopback,"sw_if_index <nn>")                                   \
22063 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22064 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22065 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22066 _(want_interface_events,  "enable|disable")                             \
22067 _(get_first_msg_id, "client <name>")                                    \
22068 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22069 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22070   "fib-id <nn> [ip4][ip6][default]")                                    \
22071 _(get_node_graph, " ")                                                  \
22072 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22073 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22074 _(ioam_disable, "")                                                     \
22075 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22076                             " sw_if_index <sw_if_index> p <priority> "  \
22077                             "w <weight>] [del]")                        \
22078 _(one_add_del_locator, "locator-set <locator_name> "                    \
22079                         "iface <intf> | sw_if_index <sw_if_index> "     \
22080                         "p <priority> w <weight> [del]")                \
22081 _(one_add_del_local_eid,"vni <vni> eid "                                \
22082                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22083                          "locator-set <locator_name> [del]"             \
22084                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22085 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22086 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22087 _(one_enable_disable, "enable|disable")                                 \
22088 _(one_map_register_enable_disable, "enable|disable")                    \
22089 _(one_map_register_fallback_threshold, "<value>")                       \
22090 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22091 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22092                                "[seid <seid>] "                         \
22093                                "rloc <locator> p <prio> "               \
22094                                "w <weight> [rloc <loc> ... ] "          \
22095                                "action <action> [del-all]")             \
22096 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22097                           "<local-eid>")                                \
22098 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22099 _(one_use_petr, "ip-address> | disable")                                \
22100 _(one_map_request_mode, "src-dst|dst-only")                             \
22101 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22102 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22103 _(one_locator_set_dump, "[local | remote]")                             \
22104 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22105 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22106                        "[local] | [remote]")                            \
22107 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22108 _(one_ndp_bd_get, "")                                                   \
22109 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22110 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22111 _(one_l2_arp_bd_get, "")                                                \
22112 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22113 _(one_stats_enable_disable, "enable|disable")                           \
22114 _(show_one_stats_enable_disable, "")                                    \
22115 _(one_eid_table_vni_dump, "")                                           \
22116 _(one_eid_table_map_dump, "l2|l3")                                      \
22117 _(one_map_resolver_dump, "")                                            \
22118 _(one_map_server_dump, "")                                              \
22119 _(one_adjacencies_get, "vni <vni>")                                     \
22120 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22121 _(show_one_rloc_probe_state, "")                                        \
22122 _(show_one_map_register_state, "")                                      \
22123 _(show_one_status, "")                                                  \
22124 _(one_stats_dump, "")                                                   \
22125 _(one_stats_flush, "")                                                  \
22126 _(one_get_map_request_itr_rlocs, "")                                    \
22127 _(one_map_register_set_ttl, "<ttl>")                                    \
22128 _(one_set_transport_protocol, "udp|api")                                \
22129 _(one_get_transport_protocol, "")                                       \
22130 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22131 _(one_show_xtr_mode, "")                                                \
22132 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22133 _(one_show_pitr_mode, "")                                               \
22134 _(one_enable_disable_petr_mode, "enable|disable")                       \
22135 _(one_show_petr_mode, "")                                               \
22136 _(show_one_nsh_mapping, "")                                             \
22137 _(show_one_pitr, "")                                                    \
22138 _(show_one_use_petr, "")                                                \
22139 _(show_one_map_request_mode, "")                                        \
22140 _(show_one_map_register_ttl, "")                                        \
22141 _(show_one_map_register_fallback_threshold, "")                         \
22142 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22143                             " sw_if_index <sw_if_index> p <priority> "  \
22144                             "w <weight>] [del]")                        \
22145 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22146                         "iface <intf> | sw_if_index <sw_if_index> "     \
22147                         "p <priority> w <weight> [del]")                \
22148 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22149                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22150                          "locator-set <locator_name> [del]"             \
22151                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22152 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22153 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22154 _(lisp_enable_disable, "enable|disable")                                \
22155 _(lisp_map_register_enable_disable, "enable|disable")                   \
22156 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22157 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22158                                "[seid <seid>] "                         \
22159                                "rloc <locator> p <prio> "               \
22160                                "w <weight> [rloc <loc> ... ] "          \
22161                                "action <action> [del-all]")             \
22162 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22163                           "<local-eid>")                                \
22164 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22165 _(lisp_use_petr, "<ip-address> | disable")                              \
22166 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22167 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22168 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22169 _(lisp_locator_set_dump, "[local | remote]")                            \
22170 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22171 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22172                        "[local] | [remote]")                            \
22173 _(lisp_eid_table_vni_dump, "")                                          \
22174 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22175 _(lisp_map_resolver_dump, "")                                           \
22176 _(lisp_map_server_dump, "")                                             \
22177 _(lisp_adjacencies_get, "vni <vni>")                                    \
22178 _(gpe_fwd_entry_vnis_get, "")                                           \
22179 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22180 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22181                                 "[table <table-id>]")                   \
22182 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22183 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22184 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22185 _(gpe_get_encap_mode, "")                                               \
22186 _(lisp_gpe_add_del_iface, "up|down")                                    \
22187 _(lisp_gpe_enable_disable, "enable|disable")                            \
22188 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22189   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22190 _(show_lisp_rloc_probe_state, "")                                       \
22191 _(show_lisp_map_register_state, "")                                     \
22192 _(show_lisp_status, "")                                                 \
22193 _(lisp_get_map_request_itr_rlocs, "")                                   \
22194 _(show_lisp_pitr, "")                                                   \
22195 _(show_lisp_use_petr, "")                                               \
22196 _(show_lisp_map_request_mode, "")                                       \
22197 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22198 _(af_packet_delete, "name <host interface name>")                       \
22199 _(af_packet_dump, "")                                                   \
22200 _(policer_add_del, "name <policer name> <params> [del]")                \
22201 _(policer_dump, "[name <policer name>]")                                \
22202 _(policer_classify_set_interface,                                       \
22203   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22204   "  [l2-table <nn>] [del]")                                            \
22205 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22206 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22207     "[master|slave]")                                                   \
22208 _(netmap_delete, "name <interface name>")                               \
22209 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22210 _(mpls_table_dump, "")                                                  \
22211 _(mpls_route_dump, "table-id <ID>")                                     \
22212 _(classify_table_ids, "")                                               \
22213 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22214 _(classify_table_info, "table_id <nn>")                                 \
22215 _(classify_session_dump, "table_id <nn>")                               \
22216 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22217     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22218     "[template_interval <nn>] [udp_checksum]")                          \
22219 _(ipfix_exporter_dump, "")                                              \
22220 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22221 _(ipfix_classify_stream_dump, "")                                       \
22222 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22223 _(ipfix_classify_table_dump, "")                                        \
22224 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22225 _(sw_interface_span_dump, "[l2]")                                           \
22226 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22227 _(pg_create_interface, "if_id <nn>")                                    \
22228 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22229 _(pg_enable_disable, "[stream <id>] disable")                           \
22230 _(ip_source_and_port_range_check_add_del,                               \
22231   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22232 _(ip_source_and_port_range_check_interface_add_del,                     \
22233   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22234   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22235 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22236 _(l2_interface_pbb_tag_rewrite,                                         \
22237   "<intfc> | sw_if_index <nn> \n"                                       \
22238   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22239   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22240 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22241 _(flow_classify_set_interface,                                          \
22242   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22243 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22244 _(ip_table_dump, "")                                                    \
22245 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22246 _(ip_mtable_dump, "")                                                   \
22247 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22248 _(feature_enable_disable, "arc_name <arc_name> "                        \
22249   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22250 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22251 "[disable]")                                                            \
22252 _(l2_xconnect_dump, "")                                                 \
22253 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22254 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22255 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22256 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22257 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22258 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22259 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22260   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22261 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22262 _(sock_init_shm, "size <nnn>")                                          \
22263 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22264 _(dns_enable_disable, "[enable][disable]")                              \
22265 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22266 _(dns_resolve_name, "<hostname>")                                       \
22267 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22268 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22269 _(dns_resolve_name, "<hostname>")                                       \
22270 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22271   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22272 _(session_rules_dump, "")                                               \
22273 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22274 _(output_acl_set_interface,                                             \
22275   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22276   "  [l2-table <nn>] [del]")                                            \
22277 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22278
22279 /* List of command functions, CLI names map directly to functions */
22280 #define foreach_cli_function                                    \
22281 _(comment, "usage: comment <ignore-rest-of-line>")              \
22282 _(dump_interface_table, "usage: dump_interface_table")          \
22283 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22284 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22285 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22286 _(dump_macro_table, "usage: dump_macro_table ")                 \
22287 _(dump_node_table, "usage: dump_node_table")                    \
22288 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22289 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22290 _(echo, "usage: echo <message>")                                \
22291 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22292 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22293 _(help, "usage: help")                                          \
22294 _(q, "usage: quit")                                             \
22295 _(quit, "usage: quit")                                          \
22296 _(search_node_table, "usage: search_node_table <name>...")      \
22297 _(set, "usage: set <variable-name> <value>")                    \
22298 _(script, "usage: script <file-name>")                          \
22299 _(statseg, "usage: statseg")                                    \
22300 _(unset, "usage: unset <variable-name>")
22301
22302 #define _(N,n)                                  \
22303     static void vl_api_##n##_t_handler_uni      \
22304     (vl_api_##n##_t * mp)                       \
22305     {                                           \
22306         vat_main_t * vam = &vat_main;           \
22307         if (vam->json_output) {                 \
22308             vl_api_##n##_t_handler_json(mp);    \
22309         } else {                                \
22310             vl_api_##n##_t_handler(mp);         \
22311         }                                       \
22312     }
22313 foreach_vpe_api_reply_msg;
22314 #if VPP_API_TEST_BUILTIN == 0
22315 foreach_standalone_reply_msg;
22316 #endif
22317 #undef _
22318
22319 void
22320 vat_api_hookup (vat_main_t * vam)
22321 {
22322 #define _(N,n)                                                  \
22323     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22324                            vl_api_##n##_t_handler_uni,          \
22325                            vl_noop_handler,                     \
22326                            vl_api_##n##_t_endian,               \
22327                            vl_api_##n##_t_print,                \
22328                            sizeof(vl_api_##n##_t), 1);
22329   foreach_vpe_api_reply_msg;
22330 #if VPP_API_TEST_BUILTIN == 0
22331   foreach_standalone_reply_msg;
22332 #endif
22333 #undef _
22334
22335 #if (VPP_API_TEST_BUILTIN==0)
22336   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22337
22338   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22339
22340   vam->function_by_name = hash_create_string (0, sizeof (uword));
22341
22342   vam->help_by_name = hash_create_string (0, sizeof (uword));
22343 #endif
22344
22345   /* API messages we can send */
22346 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22347   foreach_vpe_api_msg;
22348 #undef _
22349
22350   /* Help strings */
22351 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22352   foreach_vpe_api_msg;
22353 #undef _
22354
22355   /* CLI functions */
22356 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22357   foreach_cli_function;
22358 #undef _
22359
22360   /* Help strings */
22361 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22362   foreach_cli_function;
22363 #undef _
22364 }
22365
22366 #if VPP_API_TEST_BUILTIN
22367 static clib_error_t *
22368 vat_api_hookup_shim (vlib_main_t * vm)
22369 {
22370   vat_api_hookup (&vat_main);
22371   return 0;
22372 }
22373
22374 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22375 #endif
22376
22377 /*
22378  * fd.io coding-style-patch-verification: ON
22379  *
22380  * Local Variables:
22381  * eval: (c-set-style "gnu")
22382  * End:
22383  */