vat: vec_free/errmsh copy paste error
[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 #include <vlibapi/api_types_inlines.h>
62
63 #include <inttypes.h>
64 #include <sys/stat.h>
65
66 #define vl_typedefs             /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_typedefs
69
70 /* declare message handlers for each api */
71
72 #define vl_endianfun            /* define message structures */
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_endianfun
75
76 /* instantiate all the print functions we know about */
77 #if VPP_API_TEST_BUILTIN == 0
78 #define vl_print(handle, ...)
79 #else
80 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
81 #endif
82 #define vl_printfun
83 #include <vpp/api/vpe_all_api_h.h>
84 #undef vl_printfun
85
86 #define __plugin_msg_base 0
87 #include <vlibapi/vat_helper_macros.h>
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   vam->socket_client_main = &socket_client_main;
103   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
104                                       "vpp_api_test",
105                                       0 /* default socket rx, tx buffer */ )))
106     return rv;
107   /* vpp expects the client index in network order */
108   vam->my_client_index = htonl (socket_client_main.client_index);
109   return 0;
110 }
111 #else /* vpp built-in case, we don't do sockets... */
112 int
113 vat_socket_connect (vat_main_t * vam)
114 {
115   return 0;
116 }
117
118 int
119 vl_socket_client_read (int wait)
120 {
121   return -1;
122 };
123
124 int
125 vl_socket_client_write ()
126 {
127   return -1;
128 };
129
130 void *
131 vl_socket_client_msg_alloc (int nbytes)
132 {
133   return 0;
134 }
135 #endif
136
137
138 f64
139 vat_time_now (vat_main_t * vam)
140 {
141 #if VPP_API_TEST_BUILTIN
142   return vlib_time_now (vam->vlib_main);
143 #else
144   return clib_time_now (&vam->clib_time);
145 #endif
146 }
147
148 void
149 errmsg (char *fmt, ...)
150 {
151   vat_main_t *vam = &vat_main;
152   va_list va;
153   u8 *s;
154
155   va_start (va, fmt);
156   s = va_format (0, fmt, &va);
157   va_end (va);
158
159   vec_add1 (s, 0);
160
161 #if VPP_API_TEST_BUILTIN
162   vlib_cli_output (vam->vlib_main, (char *) s);
163 #else
164   {
165     if (vam->ifp != stdin)
166       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
167                vam->input_line_number);
168     fformat (vam->ofp, (char *) s);
169     fflush (vam->ofp);
170   }
171 #endif
172
173   vec_free (s);
174 }
175
176 #if VPP_API_TEST_BUILTIN == 0
177 static uword
178 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
179 {
180   vat_main_t *vam = va_arg (*args, vat_main_t *);
181   u32 *result = va_arg (*args, u32 *);
182   u8 *if_name;
183   uword *p;
184
185   if (!unformat (input, "%s", &if_name))
186     return 0;
187
188   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
189   if (p == 0)
190     return 0;
191   *result = p[0];
192   return 1;
193 }
194
195 static uword
196 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
197 {
198   return 0;
199 }
200
201 /* Parse an IP4 address %d.%d.%d.%d. */
202 uword
203 unformat_ip4_address (unformat_input_t * input, va_list * args)
204 {
205   u8 *result = va_arg (*args, u8 *);
206   unsigned a[4];
207
208   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
209     return 0;
210
211   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
212     return 0;
213
214   result[0] = a[0];
215   result[1] = a[1];
216   result[2] = a[2];
217   result[3] = a[3];
218
219   return 1;
220 }
221
222 uword
223 unformat_ethernet_address (unformat_input_t * input, va_list * args)
224 {
225   u8 *result = va_arg (*args, u8 *);
226   u32 i, a[6];
227
228   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
229                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
230     return 0;
231
232   /* Check range. */
233   for (i = 0; i < 6; i++)
234     if (a[i] >= (1 << 8))
235       return 0;
236
237   for (i = 0; i < 6; i++)
238     result[i] = a[i];
239
240   return 1;
241 }
242
243 /* Returns ethernet type as an int in host byte order. */
244 uword
245 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
246                                         va_list * args)
247 {
248   u16 *result = va_arg (*args, u16 *);
249   int type;
250
251   /* Numeric type. */
252   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
253     {
254       if (type >= (1 << 16))
255         return 0;
256       *result = type;
257       return 1;
258     }
259   return 0;
260 }
261
262 /* Parse an IP6 address. */
263 uword
264 unformat_ip6_address (unformat_input_t * input, va_list * args)
265 {
266   ip6_address_t *result = va_arg (*args, ip6_address_t *);
267   u16 hex_quads[8];
268   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
269   uword c, n_colon, double_colon_index;
270
271   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
272   double_colon_index = ARRAY_LEN (hex_quads);
273   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
274     {
275       hex_digit = 16;
276       if (c >= '0' && c <= '9')
277         hex_digit = c - '0';
278       else if (c >= 'a' && c <= 'f')
279         hex_digit = c + 10 - 'a';
280       else if (c >= 'A' && c <= 'F')
281         hex_digit = c + 10 - 'A';
282       else if (c == ':' && n_colon < 2)
283         n_colon++;
284       else
285         {
286           unformat_put_input (input);
287           break;
288         }
289
290       /* Too many hex quads. */
291       if (n_hex_quads >= ARRAY_LEN (hex_quads))
292         return 0;
293
294       if (hex_digit < 16)
295         {
296           hex_quad = (hex_quad << 4) | hex_digit;
297
298           /* Hex quad must fit in 16 bits. */
299           if (n_hex_digits >= 4)
300             return 0;
301
302           n_colon = 0;
303           n_hex_digits++;
304         }
305
306       /* Save position of :: */
307       if (n_colon == 2)
308         {
309           /* More than one :: ? */
310           if (double_colon_index < ARRAY_LEN (hex_quads))
311             return 0;
312           double_colon_index = n_hex_quads;
313         }
314
315       if (n_colon > 0 && n_hex_digits > 0)
316         {
317           hex_quads[n_hex_quads++] = hex_quad;
318           hex_quad = 0;
319           n_hex_digits = 0;
320         }
321     }
322
323   if (n_hex_digits > 0)
324     hex_quads[n_hex_quads++] = hex_quad;
325
326   {
327     word i;
328
329     /* Expand :: to appropriate number of zero hex quads. */
330     if (double_colon_index < ARRAY_LEN (hex_quads))
331       {
332         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
333
334         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
335           hex_quads[n_zero + i] = hex_quads[i];
336
337         for (i = 0; i < n_zero; i++)
338           hex_quads[double_colon_index + i] = 0;
339
340         n_hex_quads = ARRAY_LEN (hex_quads);
341       }
342
343     /* Too few hex quads given. */
344     if (n_hex_quads < ARRAY_LEN (hex_quads))
345       return 0;
346
347     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
348       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
349
350     return 1;
351   }
352 }
353
354 uword
355 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
356 {
357   u32 *r = va_arg (*args, u32 *);
358
359   if (0);
360 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
361   foreach_ipsec_policy_action
362 #undef _
363     else
364     return 0;
365   return 1;
366 }
367
368 u8 *
369 format_ipsec_crypto_alg (u8 * s, va_list * args)
370 {
371   u32 i = va_arg (*args, u32);
372   u8 *t = 0;
373
374   switch (i)
375     {
376 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
377       foreach_ipsec_crypto_alg
378 #undef _
379     default:
380       return format (s, "unknown");
381     }
382   return format (s, "%s", t);
383 }
384
385 u8 *
386 format_ipsec_integ_alg (u8 * s, va_list * args)
387 {
388   u32 i = va_arg (*args, u32);
389   u8 *t = 0;
390
391   switch (i)
392     {
393 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
394       foreach_ipsec_integ_alg
395 #undef _
396     default:
397       return format (s, "unknown");
398     }
399   return format (s, "%s", t);
400 }
401
402 #else /* VPP_API_TEST_BUILTIN == 1 */
403 static uword
404 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
405 {
406   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
407   vnet_main_t *vnm = vnet_get_main ();
408   u32 *result = va_arg (*args, u32 *);
409
410   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
411 }
412
413 static uword
414 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
415 {
416   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
417   vnet_main_t *vnm = vnet_get_main ();
418   u32 *result = va_arg (*args, u32 *);
419
420   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
421 }
422
423 #endif /* VPP_API_TEST_BUILTIN */
424
425 uword
426 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
432   foreach_ipsec_crypto_alg
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
446   foreach_ipsec_integ_alg
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 #if (VPP_API_TEST_BUILTIN==0)
571
572 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
573 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
574 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
575 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
576
577 uword
578 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
579 {
580   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
581   mfib_itf_attribute_t attr;
582
583   old = *iflags;
584   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
585   {
586     if (unformat (input, mfib_itf_flag_long_names[attr]))
587       *iflags |= (1 << attr);
588   }
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_names[attr]))
592       *iflags |= (1 << attr);
593   }
594
595   return (old == *iflags ? 0 : 1);
596 }
597
598 uword
599 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
602   mfib_entry_attribute_t attr;
603
604   old = *eflags;
605   FOR_EACH_MFIB_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_flag_long_names[attr]))
608       *eflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_names[attr]))
613       *eflags |= (1 << attr);
614   }
615
616   return (old == *eflags ? 0 : 1);
617 }
618
619 u8 *
620 format_ip4_address (u8 * s, va_list * args)
621 {
622   u8 *a = va_arg (*args, u8 *);
623   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
624 }
625
626 u8 *
627 format_ip6_address (u8 * s, va_list * args)
628 {
629   ip6_address_t *a = va_arg (*args, ip6_address_t *);
630   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
631
632   i_max_n_zero = ARRAY_LEN (a->as_u16);
633   max_n_zeros = 0;
634   i_first_zero = i_max_n_zero;
635   n_zeros = 0;
636   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
637     {
638       u32 is_zero = a->as_u16[i] == 0;
639       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
640         {
641           i_first_zero = i;
642           n_zeros = 0;
643         }
644       n_zeros += is_zero;
645       if ((!is_zero && n_zeros > max_n_zeros)
646           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
647         {
648           i_max_n_zero = i_first_zero;
649           max_n_zeros = n_zeros;
650           i_first_zero = ARRAY_LEN (a->as_u16);
651           n_zeros = 0;
652         }
653     }
654
655   last_double_colon = 0;
656   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
657     {
658       if (i == i_max_n_zero && max_n_zeros > 1)
659         {
660           s = format (s, "::");
661           i += max_n_zeros - 1;
662           last_double_colon = 1;
663         }
664       else
665         {
666           s = format (s, "%s%x",
667                       (last_double_colon || i == 0) ? "" : ":",
668                       clib_net_to_host_u16 (a->as_u16[i]));
669           last_double_colon = 0;
670         }
671     }
672
673   return s;
674 }
675
676 /* Format an IP46 address. */
677 u8 *
678 format_ip46_address (u8 * s, va_list * args)
679 {
680   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
681   ip46_type_t type = va_arg (*args, ip46_type_t);
682   int is_ip4 = 1;
683
684   switch (type)
685     {
686     case IP46_TYPE_ANY:
687       is_ip4 = ip46_address_is_ip4 (ip46);
688       break;
689     case IP46_TYPE_IP4:
690       is_ip4 = 1;
691       break;
692     case IP46_TYPE_IP6:
693       is_ip4 = 0;
694       break;
695     }
696
697   return is_ip4 ?
698     format (s, "%U", format_ip4_address, &ip46->ip4) :
699     format (s, "%U", format_ip6_address, &ip46->ip6);
700 }
701
702 u8 *
703 format_ethernet_address (u8 * s, va_list * args)
704 {
705   u8 *a = va_arg (*args, u8 *);
706
707   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
708                  a[0], a[1], a[2], a[3], a[4], a[5]);
709 }
710 #endif
711
712 static void
713 increment_v4_address (vl_api_ip4_address_t * i)
714 {
715   ip4_address_t *a = (ip4_address_t *) i;
716   u32 v;
717
718   v = ntohl (a->as_u32) + 1;
719   a->as_u32 = ntohl (v);
720 }
721
722 static void
723 increment_v6_address (vl_api_ip6_address_t * i)
724 {
725   ip6_address_t *a = (ip6_address_t *) i;
726   u64 v0, v1;
727
728   v0 = clib_net_to_host_u64 (a->as_u64[0]);
729   v1 = clib_net_to_host_u64 (a->as_u64[1]);
730
731   v1 += 1;
732   if (v1 == 0)
733     v0 += 1;
734   a->as_u64[0] = clib_net_to_host_u64 (v0);
735   a->as_u64[1] = clib_net_to_host_u64 (v1);
736 }
737
738 static void
739 increment_address (vl_api_address_t * a)
740 {
741   if (a->af == ADDRESS_IP4)
742     increment_v4_address (&a->un.ip4);
743   else if (a->af == ADDRESS_IP6)
744     increment_v6_address (&a->un.ip6);
745 }
746
747 static void
748 set_ip4_address (vl_api_address_t * a, u32 v)
749 {
750   if (a->af == ADDRESS_IP4)
751     {
752       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
753       i->as_u32 = v;
754     }
755 }
756
757 static void
758 increment_mac_address (u8 * mac)
759 {
760   u64 tmp = *((u64 *) mac);
761   tmp = clib_net_to_host_u64 (tmp);
762   tmp += 1 << 16;               /* skip unused (least significant) octets */
763   tmp = clib_host_to_net_u64 (tmp);
764
765   clib_memcpy (mac, &tmp, 6);
766 }
767
768 static void
769 vat_json_object_add_address (vat_json_node_t * node,
770                              const char *str, const vl_api_address_t * addr)
771 {
772   if (ADDRESS_IP6 == addr->af)
773     {
774       struct in6_addr ip6;
775
776       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
777       vat_json_object_add_ip6 (node, str, ip6);
778     }
779   else
780     {
781       struct in_addr ip4;
782
783       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
784       vat_json_object_add_ip4 (node, str, ip4);
785     }
786 }
787
788 static void
789 vat_json_object_add_prefix (vat_json_node_t * node,
790                             const vl_api_prefix_t * prefix)
791 {
792   vat_json_object_add_uint (node, "address_length", prefix->address_length);
793   vat_json_object_add_address (node, "prefix", &prefix->address);
794 }
795
796 static void vl_api_create_loopback_reply_t_handler
797   (vl_api_create_loopback_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   i32 retval = ntohl (mp->retval);
801
802   vam->retval = retval;
803   vam->regenerate_interface_table = 1;
804   vam->sw_if_index = ntohl (mp->sw_if_index);
805   vam->result_ready = 1;
806 }
807
808 static void vl_api_create_loopback_reply_t_handler_json
809   (vl_api_create_loopback_reply_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t node;
813
814   vat_json_init_object (&node);
815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
817
818   vat_json_print (vam->ofp, &node);
819   vat_json_free (&node);
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_loopback_instance_reply_t_handler
825   (vl_api_create_loopback_instance_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_loopback_instance_reply_t_handler_json
837   (vl_api_create_loopback_instance_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848   vam->retval = ntohl (mp->retval);
849   vam->result_ready = 1;
850 }
851
852 static void vl_api_af_packet_create_reply_t_handler
853   (vl_api_af_packet_create_reply_t * mp)
854 {
855   vat_main_t *vam = &vat_main;
856   i32 retval = ntohl (mp->retval);
857
858   vam->retval = retval;
859   vam->regenerate_interface_table = 1;
860   vam->sw_if_index = ntohl (mp->sw_if_index);
861   vam->result_ready = 1;
862 }
863
864 static void vl_api_af_packet_create_reply_t_handler_json
865   (vl_api_af_packet_create_reply_t * mp)
866 {
867   vat_main_t *vam = &vat_main;
868   vat_json_node_t node;
869
870   vat_json_init_object (&node);
871   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
872   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
873
874   vat_json_print (vam->ofp, &node);
875   vat_json_free (&node);
876
877   vam->retval = ntohl (mp->retval);
878   vam->result_ready = 1;
879 }
880
881 static void vl_api_create_vlan_subif_reply_t_handler
882   (vl_api_create_vlan_subif_reply_t * mp)
883 {
884   vat_main_t *vam = &vat_main;
885   i32 retval = ntohl (mp->retval);
886
887   vam->retval = retval;
888   vam->regenerate_interface_table = 1;
889   vam->sw_if_index = ntohl (mp->sw_if_index);
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_create_vlan_subif_reply_t_handler_json
894   (vl_api_create_vlan_subif_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
902
903   vat_json_print (vam->ofp, &node);
904   vat_json_free (&node);
905
906   vam->retval = ntohl (mp->retval);
907   vam->result_ready = 1;
908 }
909
910 static void vl_api_create_subif_reply_t_handler
911   (vl_api_create_subif_reply_t * mp)
912 {
913   vat_main_t *vam = &vat_main;
914   i32 retval = ntohl (mp->retval);
915
916   vam->retval = retval;
917   vam->regenerate_interface_table = 1;
918   vam->sw_if_index = ntohl (mp->sw_if_index);
919   vam->result_ready = 1;
920 }
921
922 static void vl_api_create_subif_reply_t_handler_json
923   (vl_api_create_subif_reply_t * mp)
924 {
925   vat_main_t *vam = &vat_main;
926   vat_json_node_t node;
927
928   vat_json_init_object (&node);
929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
930   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
931
932   vat_json_print (vam->ofp, &node);
933   vat_json_free (&node);
934
935   vam->retval = ntohl (mp->retval);
936   vam->result_ready = 1;
937 }
938
939 static void vl_api_interface_name_renumber_reply_t_handler
940   (vl_api_interface_name_renumber_reply_t * mp)
941 {
942   vat_main_t *vam = &vat_main;
943   i32 retval = ntohl (mp->retval);
944
945   vam->retval = retval;
946   vam->regenerate_interface_table = 1;
947   vam->result_ready = 1;
948 }
949
950 static void vl_api_interface_name_renumber_reply_t_handler_json
951   (vl_api_interface_name_renumber_reply_t * mp)
952 {
953   vat_main_t *vam = &vat_main;
954   vat_json_node_t node;
955
956   vat_json_init_object (&node);
957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958
959   vat_json_print (vam->ofp, &node);
960   vat_json_free (&node);
961
962   vam->retval = ntohl (mp->retval);
963   vam->result_ready = 1;
964 }
965
966 /*
967  * Special-case: build the interface table, maintain
968  * the next loopback sw_if_index vbl.
969  */
970 static void vl_api_sw_interface_details_t_handler
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   u8 *s = format (0, "%s%c", mp->interface_name, 0);
975
976   hash_set_mem (vam->sw_if_index_by_interface_name, s,
977                 ntohl (mp->sw_if_index));
978
979   /* In sub interface case, fill the sub interface table entry */
980   if (mp->sw_if_index != mp->sup_sw_if_index)
981     {
982       sw_interface_subif_t *sub = NULL;
983
984       vec_add2 (vam->sw_if_subif_table, sub, 1);
985
986       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
987       strncpy ((char *) sub->interface_name, (char *) s,
988                vec_len (sub->interface_name));
989       sub->sw_if_index = ntohl (mp->sw_if_index);
990       sub->sub_id = ntohl (mp->sub_id);
991
992       sub->sub_dot1ad = mp->sub_dot1ad;
993       sub->sub_number_of_tags = mp->sub_number_of_tags;
994       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
995       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
996       sub->sub_exact_match = mp->sub_exact_match;
997       sub->sub_default = mp->sub_default;
998       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
999       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
1000
1001       /* vlan tag rewrite */
1002       sub->vtr_op = ntohl (mp->vtr_op);
1003       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1004       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1005       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1006     }
1007 }
1008
1009 static void vl_api_sw_interface_details_t_handler_json
1010   (vl_api_sw_interface_details_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t *node = NULL;
1014
1015   if (VAT_JSON_ARRAY != vam->json_tree.type)
1016     {
1017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1018       vat_json_init_array (&vam->json_tree);
1019     }
1020   node = vat_json_array_add (&vam->json_tree);
1021
1022   vat_json_init_object (node);
1023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1024   vat_json_object_add_uint (node, "sup_sw_if_index",
1025                             ntohl (mp->sup_sw_if_index));
1026   vat_json_object_add_uint (node, "l2_address_length",
1027                             ntohl (mp->l2_address_length));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1033   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1034   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1035   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1036   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1037   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1038   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1046   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1047   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1048                             mp->sub_outer_vlan_id_any);
1049   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1050                             mp->sub_inner_vlan_id_any);
1051   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1052   vat_json_object_add_uint (node, "vtr_push_dot1q",
1053                             ntohl (mp->vtr_push_dot1q));
1054   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1055   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1056   if (mp->sub_dot1ah)
1057     {
1058       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1059                                        format (0, "%U",
1060                                                format_ethernet_address,
1061                                                &mp->b_dmac));
1062       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1063                                        format (0, "%U",
1064                                                format_ethernet_address,
1065                                                &mp->b_smac));
1066       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1067       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1068     }
1069 }
1070
1071 #if VPP_API_TEST_BUILTIN == 0
1072 static void vl_api_sw_interface_event_t_handler
1073   (vl_api_sw_interface_event_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   if (vam->interface_event_display)
1077     errmsg ("interface flags: sw_if_index %d %s %s",
1078             ntohl (mp->sw_if_index),
1079             mp->admin_up_down ? "admin-up" : "admin-down",
1080             mp->link_up_down ? "link-up" : "link-down");
1081 }
1082 #endif
1083
1084 __clib_unused static void
1085 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1086 {
1087   /* JSON output not supported */
1088 }
1089
1090 static void
1091 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1092 {
1093   vat_main_t *vam = &vat_main;
1094   i32 retval = ntohl (mp->retval);
1095
1096   vam->retval = retval;
1097   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106   api_main_t *am = &api_main;
1107   void *oldheap;
1108   u8 *reply;
1109
1110   vat_json_init_object (&node);
1111   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1112   vat_json_object_add_uint (&node, "reply_in_shmem",
1113                             ntohl (mp->reply_in_shmem));
1114   /* Toss the shared-memory original... */
1115   pthread_mutex_lock (&am->vlib_rp->mutex);
1116   oldheap = svm_push_data_heap (am->vlib_rp);
1117
1118   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1119   vec_free (reply);
1120
1121   svm_pop_heap (oldheap);
1122   pthread_mutex_unlock (&am->vlib_rp->mutex);
1123
1124   vat_json_print (vam->ofp, &node);
1125   vat_json_free (&node);
1126
1127   vam->retval = ntohl (mp->retval);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   i32 retval = ntohl (mp->retval);
1136   u32 length = vl_api_string_len (&mp->reply);
1137
1138   vec_reset_length (vam->cmd_reply);
1139
1140   vam->retval = retval;
1141   if (retval == 0)
1142     {
1143       vec_validate (vam->cmd_reply, length);
1144       clib_memcpy ((char *) (vam->cmd_reply),
1145                    vl_api_from_api_string (&mp->reply), length);
1146       vam->cmd_reply[length] = 0;
1147     }
1148   vam->result_ready = 1;
1149 }
1150
1151 static void
1152 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   vat_json_node_t node;
1156
1157   vec_reset_length (vam->cmd_reply);
1158
1159   vat_json_init_object (&node);
1160   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1161   vat_json_object_add_string_copy (&node, "reply",
1162                                    vl_api_from_api_string (&mp->reply));
1163
1164   vat_json_print (vam->ofp, &node);
1165   vat_json_free (&node);
1166
1167   vam->retval = ntohl (mp->retval);
1168   vam->result_ready = 1;
1169 }
1170
1171 static void vl_api_classify_add_del_table_reply_t_handler
1172   (vl_api_classify_add_del_table_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   i32 retval = ntohl (mp->retval);
1176   if (vam->async_mode)
1177     {
1178       vam->async_errors += (retval < 0);
1179     }
1180   else
1181     {
1182       vam->retval = retval;
1183       if (retval == 0 &&
1184           ((mp->new_table_index != 0xFFFFFFFF) ||
1185            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1186            (mp->match_n_vectors != 0xFFFFFFFF)))
1187         /*
1188          * Note: this is just barely thread-safe, depends on
1189          * the main thread spinning waiting for an answer...
1190          */
1191         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1192                 ntohl (mp->new_table_index),
1193                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1194       vam->result_ready = 1;
1195     }
1196 }
1197
1198 static void vl_api_classify_add_del_table_reply_t_handler_json
1199   (vl_api_classify_add_del_table_reply_t * mp)
1200 {
1201   vat_main_t *vam = &vat_main;
1202   vat_json_node_t node;
1203
1204   vat_json_init_object (&node);
1205   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1206   vat_json_object_add_uint (&node, "new_table_index",
1207                             ntohl (mp->new_table_index));
1208   vat_json_object_add_uint (&node, "skip_n_vectors",
1209                             ntohl (mp->skip_n_vectors));
1210   vat_json_object_add_uint (&node, "match_n_vectors",
1211                             ntohl (mp->match_n_vectors));
1212
1213   vat_json_print (vam->ofp, &node);
1214   vat_json_free (&node);
1215
1216   vam->retval = ntohl (mp->retval);
1217   vam->result_ready = 1;
1218 }
1219
1220 static void vl_api_get_node_index_reply_t_handler
1221   (vl_api_get_node_index_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   i32 retval = ntohl (mp->retval);
1225   if (vam->async_mode)
1226     {
1227       vam->async_errors += (retval < 0);
1228     }
1229   else
1230     {
1231       vam->retval = retval;
1232       if (retval == 0)
1233         errmsg ("node index %d", ntohl (mp->node_index));
1234       vam->result_ready = 1;
1235     }
1236 }
1237
1238 static void vl_api_get_node_index_reply_t_handler_json
1239   (vl_api_get_node_index_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   vat_json_node_t node;
1243
1244   vat_json_init_object (&node);
1245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1246   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1247
1248   vat_json_print (vam->ofp, &node);
1249   vat_json_free (&node);
1250
1251   vam->retval = ntohl (mp->retval);
1252   vam->result_ready = 1;
1253 }
1254
1255 static void vl_api_get_next_index_reply_t_handler
1256   (vl_api_get_next_index_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   i32 retval = ntohl (mp->retval);
1260   if (vam->async_mode)
1261     {
1262       vam->async_errors += (retval < 0);
1263     }
1264   else
1265     {
1266       vam->retval = retval;
1267       if (retval == 0)
1268         errmsg ("next node index %d", ntohl (mp->next_index));
1269       vam->result_ready = 1;
1270     }
1271 }
1272
1273 static void vl_api_get_next_index_reply_t_handler_json
1274   (vl_api_get_next_index_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1282
1283   vat_json_print (vam->ofp, &node);
1284   vat_json_free (&node);
1285
1286   vam->retval = ntohl (mp->retval);
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_add_node_next_reply_t_handler
1291   (vl_api_add_node_next_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   i32 retval = ntohl (mp->retval);
1295   if (vam->async_mode)
1296     {
1297       vam->async_errors += (retval < 0);
1298     }
1299   else
1300     {
1301       vam->retval = retval;
1302       if (retval == 0)
1303         errmsg ("next index %d", ntohl (mp->next_index));
1304       vam->result_ready = 1;
1305     }
1306 }
1307
1308 static void vl_api_add_node_next_reply_t_handler_json
1309   (vl_api_add_node_next_reply_t * mp)
1310 {
1311   vat_main_t *vam = &vat_main;
1312   vat_json_node_t node;
1313
1314   vat_json_init_object (&node);
1315   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1316   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1317
1318   vat_json_print (vam->ofp, &node);
1319   vat_json_free (&node);
1320
1321   vam->retval = ntohl (mp->retval);
1322   vam->result_ready = 1;
1323 }
1324
1325 static void vl_api_show_version_reply_t_handler
1326   (vl_api_show_version_reply_t * mp)
1327 {
1328   vat_main_t *vam = &vat_main;
1329   i32 retval = ntohl (mp->retval);
1330
1331   if (retval >= 0)
1332     {
1333       u8 *s = 0;
1334       char *p = (char *) &mp->program;
1335
1336       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1337       errmsg ("        program: %v\n", s);
1338       vec_free (s);
1339
1340       p +=
1341         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1342       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1343       errmsg ("        version: %v\n", s);
1344       vec_free (s);
1345
1346       p +=
1347         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1348       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1349       errmsg ("     build date: %v\n", s);
1350       vec_free (s);
1351
1352       p +=
1353         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1354       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1355       errmsg ("build directory: %v\n", s);
1356       vec_free (s);
1357     }
1358   vam->retval = retval;
1359   vam->result_ready = 1;
1360 }
1361
1362 static void vl_api_show_version_reply_t_handler_json
1363   (vl_api_show_version_reply_t * mp)
1364 {
1365   vat_main_t *vam = &vat_main;
1366   vat_json_node_t node;
1367
1368   vat_json_init_object (&node);
1369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1370   char *p = (char *) &mp->program;
1371   vat_json_object_add_string_copy (&node, "program",
1372                                    vl_api_from_api_string ((vl_api_string_t *)
1373                                                            p));
1374   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1375   vat_json_object_add_string_copy (&node, "version",
1376                                    vl_api_from_api_string ((vl_api_string_t *)
1377                                                            p));
1378   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1379   vat_json_object_add_string_copy (&node, "build_date",
1380                                    vl_api_from_api_string ((vl_api_string_t *)
1381                                                            p));
1382   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1383   vat_json_object_add_string_copy (&node, "build_directory",
1384                                    vl_api_from_api_string ((vl_api_string_t *)
1385                                                            p));
1386
1387   vat_json_print (vam->ofp, &node);
1388   vat_json_free (&node);
1389
1390   vam->retval = ntohl (mp->retval);
1391   vam->result_ready = 1;
1392 }
1393
1394 static void vl_api_show_threads_reply_t_handler
1395   (vl_api_show_threads_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   i32 retval = ntohl (mp->retval);
1399   int i, count = 0;
1400
1401   if (retval >= 0)
1402     count = ntohl (mp->count);
1403
1404   for (i = 0; i < count; i++)
1405     print (vam->ofp,
1406            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1407            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1408            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1409            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1410            ntohl (mp->thread_data[i].cpu_socket));
1411
1412   vam->retval = retval;
1413   vam->result_ready = 1;
1414 }
1415
1416 static void vl_api_show_threads_reply_t_handler_json
1417   (vl_api_show_threads_reply_t * mp)
1418 {
1419   vat_main_t *vam = &vat_main;
1420   vat_json_node_t node;
1421   vl_api_thread_data_t *td;
1422   i32 retval = ntohl (mp->retval);
1423   int i, count = 0;
1424
1425   if (retval >= 0)
1426     count = ntohl (mp->count);
1427
1428   vat_json_init_object (&node);
1429   vat_json_object_add_int (&node, "retval", retval);
1430   vat_json_object_add_uint (&node, "count", count);
1431
1432   for (i = 0; i < count; i++)
1433     {
1434       td = &mp->thread_data[i];
1435       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1436       vat_json_object_add_string_copy (&node, "name", td->name);
1437       vat_json_object_add_string_copy (&node, "type", td->type);
1438       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1439       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1440       vat_json_object_add_int (&node, "core", ntohl (td->id));
1441       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1442     }
1443
1444   vat_json_print (vam->ofp, &node);
1445   vat_json_free (&node);
1446
1447   vam->retval = retval;
1448   vam->result_ready = 1;
1449 }
1450
1451 static int
1452 api_show_threads (vat_main_t * vam)
1453 {
1454   vl_api_show_threads_t *mp;
1455   int ret;
1456
1457   print (vam->ofp,
1458          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1459          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1460
1461   M (SHOW_THREADS, mp);
1462
1463   S (mp);
1464   W (ret);
1465   return ret;
1466 }
1467
1468 static void
1469 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1470 {
1471   u32 sw_if_index = ntohl (mp->sw_if_index);
1472   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1473           mp->mac_ip ? "mac/ip binding" : "address resolution",
1474           ntohl (mp->pid), format_ip4_address, mp->ip,
1475           format_vl_api_mac_address, &mp->mac, sw_if_index);
1476 }
1477
1478 static void
1479 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 static void
1485 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1486 {
1487   u32 sw_if_index = ntohl (mp->sw_if_index);
1488   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1489           mp->mac_ip ? "mac/ip binding" : "address resolution",
1490           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1491           format_vl_api_mac_address, mp->mac, sw_if_index);
1492 }
1493
1494 static void
1495 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1496 {
1497   /* JSON output not supported */
1498 }
1499
1500 static void
1501 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1502 {
1503   u32 n_macs = ntohl (mp->n_macs);
1504   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1505           ntohl (mp->pid), mp->client_index, n_macs);
1506   int i;
1507   for (i = 0; i < n_macs; i++)
1508     {
1509       vl_api_mac_entry_t *mac = &mp->mac[i];
1510       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1511               i + 1, ntohl (mac->sw_if_index),
1512               format_ethernet_address, mac->mac_addr, mac->action);
1513       if (i == 1000)
1514         break;
1515     }
1516 }
1517
1518 static void
1519 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1520 {
1521   /* JSON output not supported */
1522 }
1523
1524 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1525 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1526
1527 /*
1528  * Special-case: build the bridge domain table, maintain
1529  * the next bd id vbl.
1530  */
1531 static void vl_api_bridge_domain_details_t_handler
1532   (vl_api_bridge_domain_details_t * mp)
1533 {
1534   vat_main_t *vam = &vat_main;
1535   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1536   int i;
1537
1538   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1539          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1540
1541   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1542          ntohl (mp->bd_id), mp->learn, mp->forward,
1543          mp->flood, ntohl (mp->bvi_sw_if_index),
1544          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1545
1546   if (n_sw_ifs)
1547     {
1548       vl_api_bridge_domain_sw_if_t *sw_ifs;
1549       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1550              "Interface Name");
1551
1552       sw_ifs = mp->sw_if_details;
1553       for (i = 0; i < n_sw_ifs; i++)
1554         {
1555           u8 *sw_if_name = 0;
1556           u32 sw_if_index;
1557           hash_pair_t *p;
1558
1559           sw_if_index = ntohl (sw_ifs->sw_if_index);
1560
1561           /* *INDENT-OFF* */
1562           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1563                              ({
1564                                if ((u32) p->value[0] == sw_if_index)
1565                                  {
1566                                    sw_if_name = (u8 *)(p->key);
1567                                    break;
1568                                  }
1569                              }));
1570           /* *INDENT-ON* */
1571           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1572                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1573                  "sw_if_index not found!");
1574
1575           sw_ifs++;
1576         }
1577     }
1578 }
1579
1580 static void vl_api_bridge_domain_details_t_handler_json
1581   (vl_api_bridge_domain_details_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t *node, *array = NULL;
1585   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1586
1587   if (VAT_JSON_ARRAY != vam->json_tree.type)
1588     {
1589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1590       vat_json_init_array (&vam->json_tree);
1591     }
1592   node = vat_json_array_add (&vam->json_tree);
1593
1594   vat_json_init_object (node);
1595   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1596   vat_json_object_add_uint (node, "flood", mp->flood);
1597   vat_json_object_add_uint (node, "forward", mp->forward);
1598   vat_json_object_add_uint (node, "learn", mp->learn);
1599   vat_json_object_add_uint (node, "bvi_sw_if_index",
1600                             ntohl (mp->bvi_sw_if_index));
1601   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1602   array = vat_json_object_add (node, "sw_if");
1603   vat_json_init_array (array);
1604
1605
1606
1607   if (n_sw_ifs)
1608     {
1609       vl_api_bridge_domain_sw_if_t *sw_ifs;
1610       int i;
1611
1612       sw_ifs = mp->sw_if_details;
1613       for (i = 0; i < n_sw_ifs; i++)
1614         {
1615           node = vat_json_array_add (array);
1616           vat_json_init_object (node);
1617           vat_json_object_add_uint (node, "sw_if_index",
1618                                     ntohl (sw_ifs->sw_if_index));
1619           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1620           sw_ifs++;
1621         }
1622     }
1623 }
1624
1625 static void vl_api_control_ping_reply_t_handler
1626   (vl_api_control_ping_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->result_ready = 1;
1638     }
1639   if (vam->socket_client_main)
1640     vam->socket_client_main->control_pings_outstanding--;
1641 }
1642
1643 static void vl_api_control_ping_reply_t_handler_json
1644   (vl_api_control_ping_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   i32 retval = ntohl (mp->retval);
1648
1649   if (VAT_JSON_NONE != vam->json_tree.type)
1650     {
1651       vat_json_print (vam->ofp, &vam->json_tree);
1652       vat_json_free (&vam->json_tree);
1653       vam->json_tree.type = VAT_JSON_NONE;
1654     }
1655   else
1656     {
1657       /* just print [] */
1658       vat_json_init_array (&vam->json_tree);
1659       vat_json_print (vam->ofp, &vam->json_tree);
1660       vam->json_tree.type = VAT_JSON_NONE;
1661     }
1662
1663   vam->retval = retval;
1664   vam->result_ready = 1;
1665 }
1666
1667 static void
1668   vl_api_bridge_domain_set_mac_age_reply_t_handler
1669   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1670 {
1671   vat_main_t *vam = &vat_main;
1672   i32 retval = ntohl (mp->retval);
1673   if (vam->async_mode)
1674     {
1675       vam->async_errors += (retval < 0);
1676     }
1677   else
1678     {
1679       vam->retval = retval;
1680       vam->result_ready = 1;
1681     }
1682 }
1683
1684 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1685   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1686 {
1687   vat_main_t *vam = &vat_main;
1688   vat_json_node_t node;
1689
1690   vat_json_init_object (&node);
1691   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1692
1693   vat_json_print (vam->ofp, &node);
1694   vat_json_free (&node);
1695
1696   vam->retval = ntohl (mp->retval);
1697   vam->result_ready = 1;
1698 }
1699
1700 static void
1701 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1702 {
1703   vat_main_t *vam = &vat_main;
1704   i32 retval = ntohl (mp->retval);
1705   if (vam->async_mode)
1706     {
1707       vam->async_errors += (retval < 0);
1708     }
1709   else
1710     {
1711       vam->retval = retval;
1712       vam->result_ready = 1;
1713     }
1714 }
1715
1716 static void vl_api_l2_flags_reply_t_handler_json
1717   (vl_api_l2_flags_reply_t * mp)
1718 {
1719   vat_main_t *vam = &vat_main;
1720   vat_json_node_t node;
1721
1722   vat_json_init_object (&node);
1723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1724   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1725                             ntohl (mp->resulting_feature_bitmap));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732 }
1733
1734 static void vl_api_bridge_flags_reply_t_handler
1735   (vl_api_bridge_flags_reply_t * mp)
1736 {
1737   vat_main_t *vam = &vat_main;
1738   i32 retval = ntohl (mp->retval);
1739   if (vam->async_mode)
1740     {
1741       vam->async_errors += (retval < 0);
1742     }
1743   else
1744     {
1745       vam->retval = retval;
1746       vam->result_ready = 1;
1747     }
1748 }
1749
1750 static void vl_api_bridge_flags_reply_t_handler_json
1751   (vl_api_bridge_flags_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1759                             ntohl (mp->resulting_feature_bitmap));
1760
1761   vat_json_print (vam->ofp, &node);
1762   vat_json_free (&node);
1763
1764   vam->retval = ntohl (mp->retval);
1765   vam->result_ready = 1;
1766 }
1767
1768 static void
1769 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783
1784 }
1785
1786 static void vl_api_tap_create_v2_reply_t_handler_json
1787   (vl_api_tap_create_v2_reply_t * mp)
1788 {
1789   vat_main_t *vam = &vat_main;
1790   vat_json_node_t node;
1791
1792   vat_json_init_object (&node);
1793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1794   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1795
1796   vat_json_print (vam->ofp, &node);
1797   vat_json_free (&node);
1798
1799   vam->retval = ntohl (mp->retval);
1800   vam->result_ready = 1;
1801
1802 }
1803
1804 static void
1805 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1806 {
1807   vat_main_t *vam = &vat_main;
1808   i32 retval = ntohl (mp->retval);
1809   if (vam->async_mode)
1810     {
1811       vam->async_errors += (retval < 0);
1812     }
1813   else
1814     {
1815       vam->retval = retval;
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_tap_delete_v2_reply_t_handler_json
1821   (vl_api_tap_delete_v2_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834 }
1835
1836 static void
1837 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1838                                           mp)
1839 {
1840   vat_main_t *vam = &vat_main;
1841   i32 retval = ntohl (mp->retval);
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->sw_if_index = ntohl (mp->sw_if_index);
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_virtio_pci_create_reply_t_handler_json
1855   (vl_api_virtio_pci_create_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869
1870 }
1871
1872 static void
1873 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1874                                           mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   i32 retval = ntohl (mp->retval);
1878   if (vam->async_mode)
1879     {
1880       vam->async_errors += (retval < 0);
1881     }
1882   else
1883     {
1884       vam->retval = retval;
1885       vam->result_ready = 1;
1886     }
1887 }
1888
1889 static void vl_api_virtio_pci_delete_reply_t_handler_json
1890   (vl_api_virtio_pci_delete_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   vat_json_node_t node;
1894
1895   vat_json_init_object (&node);
1896   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1897
1898   vat_json_print (vam->ofp, &node);
1899   vat_json_free (&node);
1900
1901   vam->retval = ntohl (mp->retval);
1902   vam->result_ready = 1;
1903 }
1904
1905 static void
1906 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1907 {
1908   vat_main_t *vam = &vat_main;
1909   i32 retval = ntohl (mp->retval);
1910
1911   if (vam->async_mode)
1912     {
1913       vam->async_errors += (retval < 0);
1914     }
1915   else
1916     {
1917       vam->retval = retval;
1918       vam->sw_if_index = ntohl (mp->sw_if_index);
1919       vam->result_ready = 1;
1920     }
1921 }
1922
1923 static void vl_api_bond_create_reply_t_handler_json
1924   (vl_api_bond_create_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   vat_json_node_t node;
1928
1929   vat_json_init_object (&node);
1930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1931   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1932
1933   vat_json_print (vam->ofp, &node);
1934   vat_json_free (&node);
1935
1936   vam->retval = ntohl (mp->retval);
1937   vam->result_ready = 1;
1938 }
1939
1940 static void
1941 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1942 {
1943   vat_main_t *vam = &vat_main;
1944   i32 retval = ntohl (mp->retval);
1945
1946   if (vam->async_mode)
1947     {
1948       vam->async_errors += (retval < 0);
1949     }
1950   else
1951     {
1952       vam->retval = retval;
1953       vam->result_ready = 1;
1954     }
1955 }
1956
1957 static void vl_api_bond_delete_reply_t_handler_json
1958   (vl_api_bond_delete_reply_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t node;
1962
1963   vat_json_init_object (&node);
1964   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1965
1966   vat_json_print (vam->ofp, &node);
1967   vat_json_free (&node);
1968
1969   vam->retval = ntohl (mp->retval);
1970   vam->result_ready = 1;
1971 }
1972
1973 static void
1974 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   i32 retval = ntohl (mp->retval);
1978
1979   if (vam->async_mode)
1980     {
1981       vam->async_errors += (retval < 0);
1982     }
1983   else
1984     {
1985       vam->retval = retval;
1986       vam->result_ready = 1;
1987     }
1988 }
1989
1990 static void vl_api_bond_enslave_reply_t_handler_json
1991   (vl_api_bond_enslave_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   vat_json_node_t node;
1995
1996   vat_json_init_object (&node);
1997   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static void
2007 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2008                                           mp)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   i32 retval = ntohl (mp->retval);
2012
2013   if (vam->async_mode)
2014     {
2015       vam->async_errors += (retval < 0);
2016     }
2017   else
2018     {
2019       vam->retval = retval;
2020       vam->result_ready = 1;
2021     }
2022 }
2023
2024 static void vl_api_bond_detach_slave_reply_t_handler_json
2025   (vl_api_bond_detach_slave_reply_t * mp)
2026 {
2027   vat_main_t *vam = &vat_main;
2028   vat_json_node_t node;
2029
2030   vat_json_init_object (&node);
2031   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2032
2033   vat_json_print (vam->ofp, &node);
2034   vat_json_free (&node);
2035
2036   vam->retval = ntohl (mp->retval);
2037   vam->result_ready = 1;
2038 }
2039
2040 static void vl_api_sw_interface_bond_details_t_handler
2041   (vl_api_sw_interface_bond_details_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044
2045   print (vam->ofp,
2046          "%-16s %-12d %-12U %-13U %-14u %-14u",
2047          mp->interface_name, ntohl (mp->sw_if_index),
2048          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2049          ntohl (mp->active_slaves), ntohl (mp->slaves));
2050 }
2051
2052 static void vl_api_sw_interface_bond_details_t_handler_json
2053   (vl_api_sw_interface_bond_details_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   vat_json_node_t *node = NULL;
2057
2058   if (VAT_JSON_ARRAY != vam->json_tree.type)
2059     {
2060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2061       vat_json_init_array (&vam->json_tree);
2062     }
2063   node = vat_json_array_add (&vam->json_tree);
2064
2065   vat_json_init_object (node);
2066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2067   vat_json_object_add_string_copy (node, "interface_name",
2068                                    mp->interface_name);
2069   vat_json_object_add_uint (node, "mode", mp->mode);
2070   vat_json_object_add_uint (node, "load_balance", mp->lb);
2071   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2072   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2073 }
2074
2075 static int
2076 api_sw_interface_bond_dump (vat_main_t * vam)
2077 {
2078   vl_api_sw_interface_bond_dump_t *mp;
2079   vl_api_control_ping_t *mp_ping;
2080   int ret;
2081
2082   print (vam->ofp,
2083          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2084          "interface name", "sw_if_index", "mode", "load balance",
2085          "active slaves", "slaves");
2086
2087   /* Get list of bond interfaces */
2088   M (SW_INTERFACE_BOND_DUMP, mp);
2089   S (mp);
2090
2091   /* Use a control ping for synchronization */
2092   MPING (CONTROL_PING, mp_ping);
2093   S (mp_ping);
2094
2095   W (ret);
2096   return ret;
2097 }
2098
2099 static void vl_api_sw_interface_slave_details_t_handler
2100   (vl_api_sw_interface_slave_details_t * mp)
2101 {
2102   vat_main_t *vam = &vat_main;
2103
2104   print (vam->ofp,
2105          "%-25s %-12d %-12d %d", mp->interface_name,
2106          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2107 }
2108
2109 static void vl_api_sw_interface_slave_details_t_handler_json
2110   (vl_api_sw_interface_slave_details_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113   vat_json_node_t *node = NULL;
2114
2115   if (VAT_JSON_ARRAY != vam->json_tree.type)
2116     {
2117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2118       vat_json_init_array (&vam->json_tree);
2119     }
2120   node = vat_json_array_add (&vam->json_tree);
2121
2122   vat_json_init_object (node);
2123   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2124   vat_json_object_add_string_copy (node, "interface_name",
2125                                    mp->interface_name);
2126   vat_json_object_add_uint (node, "passive", mp->is_passive);
2127   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2128 }
2129
2130 static int
2131 api_sw_interface_slave_dump (vat_main_t * vam)
2132 {
2133   unformat_input_t *i = vam->input;
2134   vl_api_sw_interface_slave_dump_t *mp;
2135   vl_api_control_ping_t *mp_ping;
2136   u32 sw_if_index = ~0;
2137   u8 sw_if_index_set = 0;
2138   int ret;
2139
2140   /* Parse args required to build the message */
2141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2142     {
2143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2144         sw_if_index_set = 1;
2145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2146         sw_if_index_set = 1;
2147       else
2148         break;
2149     }
2150
2151   if (sw_if_index_set == 0)
2152     {
2153       errmsg ("missing vpp interface name. ");
2154       return -99;
2155     }
2156
2157   print (vam->ofp,
2158          "\n%-25s %-12s %-12s %s",
2159          "slave interface name", "sw_if_index", "passive", "long_timeout");
2160
2161   /* Get list of bond interfaces */
2162   M (SW_INTERFACE_SLAVE_DUMP, mp);
2163   mp->sw_if_index = ntohl (sw_if_index);
2164   S (mp);
2165
2166   /* Use a control ping for synchronization */
2167   MPING (CONTROL_PING, mp_ping);
2168   S (mp_ping);
2169
2170   W (ret);
2171   return ret;
2172 }
2173
2174 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2175   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   i32 retval = ntohl (mp->retval);
2179   if (vam->async_mode)
2180     {
2181       vam->async_errors += (retval < 0);
2182     }
2183   else
2184     {
2185       vam->retval = retval;
2186       vam->sw_if_index = ntohl (mp->sw_if_index);
2187       vam->result_ready = 1;
2188     }
2189   vam->regenerate_interface_table = 1;
2190 }
2191
2192 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2193   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2194 {
2195   vat_main_t *vam = &vat_main;
2196   vat_json_node_t node;
2197
2198   vat_json_init_object (&node);
2199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2200   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2201                             ntohl (mp->sw_if_index));
2202
2203   vat_json_print (vam->ofp, &node);
2204   vat_json_free (&node);
2205
2206   vam->retval = ntohl (mp->retval);
2207   vam->result_ready = 1;
2208 }
2209
2210 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2211   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2212 {
2213   vat_main_t *vam = &vat_main;
2214   i32 retval = ntohl (mp->retval);
2215   if (vam->async_mode)
2216     {
2217       vam->async_errors += (retval < 0);
2218     }
2219   else
2220     {
2221       vam->retval = retval;
2222       vam->sw_if_index = ntohl (mp->sw_if_index);
2223       vam->result_ready = 1;
2224     }
2225 }
2226
2227 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2228   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2229 {
2230   vat_main_t *vam = &vat_main;
2231   vat_json_node_t node;
2232
2233   vat_json_init_object (&node);
2234   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2235   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2236
2237   vat_json_print (vam->ofp, &node);
2238   vat_json_free (&node);
2239
2240   vam->retval = ntohl (mp->retval);
2241   vam->result_ready = 1;
2242 }
2243
2244 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2245   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   i32 retval = ntohl (mp->retval);
2249   if (vam->async_mode)
2250     {
2251       vam->async_errors += (retval < 0);
2252     }
2253   else
2254     {
2255       vam->retval = retval;
2256       vam->result_ready = 1;
2257     }
2258 }
2259
2260 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2261   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   vat_json_node_t node;
2265
2266   vat_json_init_object (&node);
2267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2268   vat_json_object_add_uint (&node, "fwd_entry_index",
2269                             clib_net_to_host_u32 (mp->fwd_entry_index));
2270
2271   vat_json_print (vam->ofp, &node);
2272   vat_json_free (&node);
2273
2274   vam->retval = ntohl (mp->retval);
2275   vam->result_ready = 1;
2276 }
2277
2278 u8 *
2279 format_lisp_transport_protocol (u8 * s, va_list * args)
2280 {
2281   u32 proto = va_arg (*args, u32);
2282
2283   switch (proto)
2284     {
2285     case 1:
2286       return format (s, "udp");
2287     case 2:
2288       return format (s, "api");
2289     default:
2290       return 0;
2291     }
2292   return 0;
2293 }
2294
2295 static void vl_api_one_get_transport_protocol_reply_t_handler
2296   (vl_api_one_get_transport_protocol_reply_t * mp)
2297 {
2298   vat_main_t *vam = &vat_main;
2299   i32 retval = ntohl (mp->retval);
2300   if (vam->async_mode)
2301     {
2302       vam->async_errors += (retval < 0);
2303     }
2304   else
2305     {
2306       u32 proto = mp->protocol;
2307       print (vam->ofp, "Transport protocol: %U",
2308              format_lisp_transport_protocol, proto);
2309       vam->retval = retval;
2310       vam->result_ready = 1;
2311     }
2312 }
2313
2314 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2315   (vl_api_one_get_transport_protocol_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   vat_json_node_t node;
2319   u8 *s;
2320
2321   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2322   vec_add1 (s, 0);
2323
2324   vat_json_init_object (&node);
2325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2326   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2327
2328   vec_free (s);
2329   vat_json_print (vam->ofp, &node);
2330   vat_json_free (&node);
2331
2332   vam->retval = ntohl (mp->retval);
2333   vam->result_ready = 1;
2334 }
2335
2336 static void vl_api_one_add_del_locator_set_reply_t_handler
2337   (vl_api_one_add_del_locator_set_reply_t * mp)
2338 {
2339   vat_main_t *vam = &vat_main;
2340   i32 retval = ntohl (mp->retval);
2341   if (vam->async_mode)
2342     {
2343       vam->async_errors += (retval < 0);
2344     }
2345   else
2346     {
2347       vam->retval = retval;
2348       vam->result_ready = 1;
2349     }
2350 }
2351
2352 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2353   (vl_api_one_add_del_locator_set_reply_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   vat_json_node_t node;
2357
2358   vat_json_init_object (&node);
2359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2360   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2361
2362   vat_json_print (vam->ofp, &node);
2363   vat_json_free (&node);
2364
2365   vam->retval = ntohl (mp->retval);
2366   vam->result_ready = 1;
2367 }
2368
2369 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2370   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   i32 retval = ntohl (mp->retval);
2374   if (vam->async_mode)
2375     {
2376       vam->async_errors += (retval < 0);
2377     }
2378   else
2379     {
2380       vam->retval = retval;
2381       vam->sw_if_index = ntohl (mp->sw_if_index);
2382       vam->result_ready = 1;
2383     }
2384   vam->regenerate_interface_table = 1;
2385 }
2386
2387 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2388   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2389 {
2390   vat_main_t *vam = &vat_main;
2391   vat_json_node_t node;
2392
2393   vat_json_init_object (&node);
2394   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2395   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void vl_api_vxlan_offload_rx_reply_t_handler
2405   (vl_api_vxlan_offload_rx_reply_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   i32 retval = ntohl (mp->retval);
2409   if (vam->async_mode)
2410     {
2411       vam->async_errors += (retval < 0);
2412     }
2413   else
2414     {
2415       vam->retval = retval;
2416       vam->result_ready = 1;
2417     }
2418 }
2419
2420 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2421   (vl_api_vxlan_offload_rx_reply_t * mp)
2422 {
2423   vat_main_t *vam = &vat_main;
2424   vat_json_node_t node;
2425
2426   vat_json_init_object (&node);
2427   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2428
2429   vat_json_print (vam->ofp, &node);
2430   vat_json_free (&node);
2431
2432   vam->retval = ntohl (mp->retval);
2433   vam->result_ready = 1;
2434 }
2435
2436 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2437   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2438 {
2439   vat_main_t *vam = &vat_main;
2440   i32 retval = ntohl (mp->retval);
2441   if (vam->async_mode)
2442     {
2443       vam->async_errors += (retval < 0);
2444     }
2445   else
2446     {
2447       vam->retval = retval;
2448       vam->sw_if_index = ntohl (mp->sw_if_index);
2449       vam->result_ready = 1;
2450     }
2451 }
2452
2453 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2454   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2455 {
2456   vat_main_t *vam = &vat_main;
2457   vat_json_node_t node;
2458
2459   vat_json_init_object (&node);
2460   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2461   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2462
2463   vat_json_print (vam->ofp, &node);
2464   vat_json_free (&node);
2465
2466   vam->retval = ntohl (mp->retval);
2467   vam->result_ready = 1;
2468 }
2469
2470 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2471   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2472 {
2473   vat_main_t *vam = &vat_main;
2474   i32 retval = ntohl (mp->retval);
2475   if (vam->async_mode)
2476     {
2477       vam->async_errors += (retval < 0);
2478     }
2479   else
2480     {
2481       vam->retval = retval;
2482       vam->sw_if_index = ntohl (mp->sw_if_index);
2483       vam->result_ready = 1;
2484     }
2485   vam->regenerate_interface_table = 1;
2486 }
2487
2488 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2489   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2490 {
2491   vat_main_t *vam = &vat_main;
2492   vat_json_node_t node;
2493
2494   vat_json_init_object (&node);
2495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2496   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2497
2498   vat_json_print (vam->ofp, &node);
2499   vat_json_free (&node);
2500
2501   vam->retval = ntohl (mp->retval);
2502   vam->result_ready = 1;
2503 }
2504
2505 static void vl_api_gre_tunnel_add_del_reply_t_handler
2506   (vl_api_gre_tunnel_add_del_reply_t * mp)
2507 {
2508   vat_main_t *vam = &vat_main;
2509   i32 retval = ntohl (mp->retval);
2510   if (vam->async_mode)
2511     {
2512       vam->async_errors += (retval < 0);
2513     }
2514   else
2515     {
2516       vam->retval = retval;
2517       vam->sw_if_index = ntohl (mp->sw_if_index);
2518       vam->result_ready = 1;
2519     }
2520 }
2521
2522 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2523   (vl_api_gre_tunnel_add_del_reply_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   vat_json_node_t node;
2527
2528   vat_json_init_object (&node);
2529   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2530   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2531
2532   vat_json_print (vam->ofp, &node);
2533   vat_json_free (&node);
2534
2535   vam->retval = ntohl (mp->retval);
2536   vam->result_ready = 1;
2537 }
2538
2539 static void vl_api_create_vhost_user_if_reply_t_handler
2540   (vl_api_create_vhost_user_if_reply_t * mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   i32 retval = ntohl (mp->retval);
2544   if (vam->async_mode)
2545     {
2546       vam->async_errors += (retval < 0);
2547     }
2548   else
2549     {
2550       vam->retval = retval;
2551       vam->sw_if_index = ntohl (mp->sw_if_index);
2552       vam->result_ready = 1;
2553     }
2554   vam->regenerate_interface_table = 1;
2555 }
2556
2557 static void vl_api_create_vhost_user_if_reply_t_handler_json
2558   (vl_api_create_vhost_user_if_reply_t * mp)
2559 {
2560   vat_main_t *vam = &vat_main;
2561   vat_json_node_t node;
2562
2563   vat_json_init_object (&node);
2564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2565   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2566
2567   vat_json_print (vam->ofp, &node);
2568   vat_json_free (&node);
2569
2570   vam->retval = ntohl (mp->retval);
2571   vam->result_ready = 1;
2572 }
2573
2574 static void vl_api_dns_resolve_name_reply_t_handler
2575   (vl_api_dns_resolve_name_reply_t * mp)
2576 {
2577   vat_main_t *vam = &vat_main;
2578   i32 retval = ntohl (mp->retval);
2579   if (vam->async_mode)
2580     {
2581       vam->async_errors += (retval < 0);
2582     }
2583   else
2584     {
2585       vam->retval = retval;
2586       vam->result_ready = 1;
2587
2588       if (retval == 0)
2589         {
2590           if (mp->ip4_set)
2591             clib_warning ("ip4 address %U", format_ip4_address,
2592                           (ip4_address_t *) mp->ip4_address);
2593           if (mp->ip6_set)
2594             clib_warning ("ip6 address %U", format_ip6_address,
2595                           (ip6_address_t *) mp->ip6_address);
2596         }
2597       else
2598         clib_warning ("retval %d", retval);
2599     }
2600 }
2601
2602 static void vl_api_dns_resolve_name_reply_t_handler_json
2603   (vl_api_dns_resolve_name_reply_t * mp)
2604 {
2605   clib_warning ("not implemented");
2606 }
2607
2608 static void vl_api_dns_resolve_ip_reply_t_handler
2609   (vl_api_dns_resolve_ip_reply_t * mp)
2610 {
2611   vat_main_t *vam = &vat_main;
2612   i32 retval = ntohl (mp->retval);
2613   if (vam->async_mode)
2614     {
2615       vam->async_errors += (retval < 0);
2616     }
2617   else
2618     {
2619       vam->retval = retval;
2620       vam->result_ready = 1;
2621
2622       if (retval == 0)
2623         {
2624           clib_warning ("canonical name %s", mp->name);
2625         }
2626       else
2627         clib_warning ("retval %d", retval);
2628     }
2629 }
2630
2631 static void vl_api_dns_resolve_ip_reply_t_handler_json
2632   (vl_api_dns_resolve_ip_reply_t * mp)
2633 {
2634   clib_warning ("not implemented");
2635 }
2636
2637
2638 static void vl_api_ip_address_details_t_handler
2639   (vl_api_ip_address_details_t * mp)
2640 {
2641   vat_main_t *vam = &vat_main;
2642   static ip_address_details_t empty_ip_address_details = { {0} };
2643   ip_address_details_t *address = NULL;
2644   ip_details_t *current_ip_details = NULL;
2645   ip_details_t *details = NULL;
2646
2647   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2648
2649   if (!details || vam->current_sw_if_index >= vec_len (details)
2650       || !details[vam->current_sw_if_index].present)
2651     {
2652       errmsg ("ip address details arrived but not stored");
2653       errmsg ("ip_dump should be called first");
2654       return;
2655     }
2656
2657   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2658
2659 #define addresses (current_ip_details->addr)
2660
2661   vec_validate_init_empty (addresses, vec_len (addresses),
2662                            empty_ip_address_details);
2663
2664   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2665
2666   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2667   address->prefix_length = mp->prefix.address_length;
2668 #undef addresses
2669 }
2670
2671 static void vl_api_ip_address_details_t_handler_json
2672   (vl_api_ip_address_details_t * mp)
2673 {
2674   vat_main_t *vam = &vat_main;
2675   vat_json_node_t *node = NULL;
2676
2677   if (VAT_JSON_ARRAY != vam->json_tree.type)
2678     {
2679       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2680       vat_json_init_array (&vam->json_tree);
2681     }
2682   node = vat_json_array_add (&vam->json_tree);
2683
2684   vat_json_init_object (node);
2685   vat_json_object_add_prefix (node, &mp->prefix);
2686 }
2687
2688 static void
2689 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2690 {
2691   vat_main_t *vam = &vat_main;
2692   static ip_details_t empty_ip_details = { 0 };
2693   ip_details_t *ip = NULL;
2694   u32 sw_if_index = ~0;
2695
2696   sw_if_index = ntohl (mp->sw_if_index);
2697
2698   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2699                            sw_if_index, empty_ip_details);
2700
2701   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2702                          sw_if_index);
2703
2704   ip->present = 1;
2705 }
2706
2707 static void
2708 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2709 {
2710   vat_main_t *vam = &vat_main;
2711
2712   if (VAT_JSON_ARRAY != vam->json_tree.type)
2713     {
2714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2715       vat_json_init_array (&vam->json_tree);
2716     }
2717   vat_json_array_add_uint (&vam->json_tree,
2718                            clib_net_to_host_u32 (mp->sw_if_index));
2719 }
2720
2721 static void
2722 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2723 {
2724   u8 *s, i;
2725
2726   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2727               "host_mac %U router_addr %U",
2728               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2729               mp->lease.hostname,
2730               format_ip4_address, mp->lease.host_address,
2731               format_ethernet_address, mp->lease.host_mac,
2732               format_ip4_address, mp->lease.router_address);
2733
2734   for (i = 0; i < mp->lease.count; i++)
2735     s =
2736       format (s, " domain_server_addr %U", format_ip4_address,
2737               mp->lease.domain_server[i].address);
2738
2739   errmsg ((char *) s);
2740   vec_free (s);
2741 }
2742
2743 static void vl_api_dhcp_compl_event_t_handler_json
2744   (vl_api_dhcp_compl_event_t * mp)
2745 {
2746   /* JSON output not supported */
2747 }
2748
2749 static void vl_api_get_first_msg_id_reply_t_handler
2750   (vl_api_get_first_msg_id_reply_t * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753   i32 retval = ntohl (mp->retval);
2754
2755   if (vam->async_mode)
2756     {
2757       vam->async_errors += (retval < 0);
2758     }
2759   else
2760     {
2761       vam->retval = retval;
2762       vam->result_ready = 1;
2763     }
2764   if (retval >= 0)
2765     {
2766       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2767     }
2768 }
2769
2770 static void vl_api_get_first_msg_id_reply_t_handler_json
2771   (vl_api_get_first_msg_id_reply_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vat_json_node_t node;
2775
2776   vat_json_init_object (&node);
2777   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2778   vat_json_object_add_uint (&node, "first_msg_id",
2779                             (uint) ntohs (mp->first_msg_id));
2780
2781   vat_json_print (vam->ofp, &node);
2782   vat_json_free (&node);
2783
2784   vam->retval = ntohl (mp->retval);
2785   vam->result_ready = 1;
2786 }
2787
2788 static void vl_api_get_node_graph_reply_t_handler
2789   (vl_api_get_node_graph_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   api_main_t *am = &api_main;
2793   i32 retval = ntohl (mp->retval);
2794   u8 *pvt_copy, *reply;
2795   void *oldheap;
2796   vlib_node_t *node;
2797   int i;
2798
2799   if (vam->async_mode)
2800     {
2801       vam->async_errors += (retval < 0);
2802     }
2803   else
2804     {
2805       vam->retval = retval;
2806       vam->result_ready = 1;
2807     }
2808
2809   /* "Should never happen..." */
2810   if (retval != 0)
2811     return;
2812
2813   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2814   pvt_copy = vec_dup (reply);
2815
2816   /* Toss the shared-memory original... */
2817   pthread_mutex_lock (&am->vlib_rp->mutex);
2818   oldheap = svm_push_data_heap (am->vlib_rp);
2819
2820   vec_free (reply);
2821
2822   svm_pop_heap (oldheap);
2823   pthread_mutex_unlock (&am->vlib_rp->mutex);
2824
2825   if (vam->graph_nodes)
2826     {
2827       hash_free (vam->graph_node_index_by_name);
2828
2829       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2830         {
2831           node = vam->graph_nodes[0][i];
2832           vec_free (node->name);
2833           vec_free (node->next_nodes);
2834           vec_free (node);
2835         }
2836       vec_free (vam->graph_nodes[0]);
2837       vec_free (vam->graph_nodes);
2838     }
2839
2840   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2841   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2842   vec_free (pvt_copy);
2843
2844   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2845     {
2846       node = vam->graph_nodes[0][i];
2847       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2848     }
2849 }
2850
2851 static void vl_api_get_node_graph_reply_t_handler_json
2852   (vl_api_get_node_graph_reply_t * mp)
2853 {
2854   vat_main_t *vam = &vat_main;
2855   api_main_t *am = &api_main;
2856   void *oldheap;
2857   vat_json_node_t node;
2858   u8 *reply;
2859
2860   /* $$$$ make this real? */
2861   vat_json_init_object (&node);
2862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2863   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866
2867   /* Toss the shared-memory original... */
2868   pthread_mutex_lock (&am->vlib_rp->mutex);
2869   oldheap = svm_push_data_heap (am->vlib_rp);
2870
2871   vec_free (reply);
2872
2873   svm_pop_heap (oldheap);
2874   pthread_mutex_unlock (&am->vlib_rp->mutex);
2875
2876   vat_json_print (vam->ofp, &node);
2877   vat_json_free (&node);
2878
2879   vam->retval = ntohl (mp->retval);
2880   vam->result_ready = 1;
2881 }
2882
2883 static void
2884 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   u8 *s = 0;
2888
2889   if (mp->local)
2890     {
2891       s = format (s, "%=16d%=16d%=16d",
2892                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2893     }
2894   else
2895     {
2896       s = format (s, "%=16U%=16d%=16d",
2897                   mp->is_ipv6 ? format_ip6_address :
2898                   format_ip4_address,
2899                   mp->ip_address, mp->priority, mp->weight);
2900     }
2901
2902   print (vam->ofp, "%v", s);
2903   vec_free (s);
2904 }
2905
2906 static void
2907 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910   vat_json_node_t *node = NULL;
2911   struct in6_addr ip6;
2912   struct in_addr ip4;
2913
2914   if (VAT_JSON_ARRAY != vam->json_tree.type)
2915     {
2916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2917       vat_json_init_array (&vam->json_tree);
2918     }
2919   node = vat_json_array_add (&vam->json_tree);
2920   vat_json_init_object (node);
2921
2922   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2923   vat_json_object_add_uint (node, "priority", mp->priority);
2924   vat_json_object_add_uint (node, "weight", mp->weight);
2925
2926   if (mp->local)
2927     vat_json_object_add_uint (node, "sw_if_index",
2928                               clib_net_to_host_u32 (mp->sw_if_index));
2929   else
2930     {
2931       if (mp->is_ipv6)
2932         {
2933           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2934           vat_json_object_add_ip6 (node, "address", ip6);
2935         }
2936       else
2937         {
2938           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2939           vat_json_object_add_ip4 (node, "address", ip4);
2940         }
2941     }
2942 }
2943
2944 static void
2945 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2946                                           mp)
2947 {
2948   vat_main_t *vam = &vat_main;
2949   u8 *ls_name = 0;
2950
2951   ls_name = format (0, "%s", mp->ls_name);
2952
2953   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2954          ls_name);
2955   vec_free (ls_name);
2956 }
2957
2958 static void
2959   vl_api_one_locator_set_details_t_handler_json
2960   (vl_api_one_locator_set_details_t * mp)
2961 {
2962   vat_main_t *vam = &vat_main;
2963   vat_json_node_t *node = 0;
2964   u8 *ls_name = 0;
2965
2966   ls_name = format (0, "%s", mp->ls_name);
2967   vec_add1 (ls_name, 0);
2968
2969   if (VAT_JSON_ARRAY != vam->json_tree.type)
2970     {
2971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2972       vat_json_init_array (&vam->json_tree);
2973     }
2974   node = vat_json_array_add (&vam->json_tree);
2975
2976   vat_json_init_object (node);
2977   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2978   vat_json_object_add_uint (node, "ls_index",
2979                             clib_net_to_host_u32 (mp->ls_index));
2980   vec_free (ls_name);
2981 }
2982
2983 typedef struct
2984 {
2985   u32 spi;
2986   u8 si;
2987 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2988
2989 uword
2990 unformat_nsh_address (unformat_input_t * input, va_list * args)
2991 {
2992   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2993   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2994 }
2995
2996 u8 *
2997 format_nsh_address_vat (u8 * s, va_list * args)
2998 {
2999   nsh_t *a = va_arg (*args, nsh_t *);
3000   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3001 }
3002
3003 static u8 *
3004 format_lisp_flat_eid (u8 * s, va_list * args)
3005 {
3006   u32 type = va_arg (*args, u32);
3007   u8 *eid = va_arg (*args, u8 *);
3008   u32 eid_len = va_arg (*args, u32);
3009
3010   switch (type)
3011     {
3012     case 0:
3013       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3014     case 1:
3015       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3016     case 2:
3017       return format (s, "%U", format_ethernet_address, eid);
3018     case 3:
3019       return format (s, "%U", format_nsh_address_vat, eid);
3020     }
3021   return 0;
3022 }
3023
3024 static u8 *
3025 format_lisp_eid_vat (u8 * s, va_list * args)
3026 {
3027   u32 type = va_arg (*args, u32);
3028   u8 *eid = va_arg (*args, u8 *);
3029   u32 eid_len = va_arg (*args, u32);
3030   u8 *seid = va_arg (*args, u8 *);
3031   u32 seid_len = va_arg (*args, u32);
3032   u32 is_src_dst = va_arg (*args, u32);
3033
3034   if (is_src_dst)
3035     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3036
3037   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3038
3039   return s;
3040 }
3041
3042 static void
3043 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3044 {
3045   vat_main_t *vam = &vat_main;
3046   u8 *s = 0, *eid = 0;
3047
3048   if (~0 == mp->locator_set_index)
3049     s = format (0, "action: %d", mp->action);
3050   else
3051     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3052
3053   eid = format (0, "%U", format_lisp_eid_vat,
3054                 mp->eid_type,
3055                 mp->eid,
3056                 mp->eid_prefix_len,
3057                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3058   vec_add1 (eid, 0);
3059
3060   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3061          clib_net_to_host_u32 (mp->vni),
3062          eid,
3063          mp->is_local ? "local" : "remote",
3064          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3065          clib_net_to_host_u16 (mp->key_id), mp->key);
3066
3067   vec_free (s);
3068   vec_free (eid);
3069 }
3070
3071 static void
3072 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3073                                              * mp)
3074 {
3075   vat_main_t *vam = &vat_main;
3076   vat_json_node_t *node = 0;
3077   u8 *eid = 0;
3078
3079   if (VAT_JSON_ARRAY != vam->json_tree.type)
3080     {
3081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3082       vat_json_init_array (&vam->json_tree);
3083     }
3084   node = vat_json_array_add (&vam->json_tree);
3085
3086   vat_json_init_object (node);
3087   if (~0 == mp->locator_set_index)
3088     vat_json_object_add_uint (node, "action", mp->action);
3089   else
3090     vat_json_object_add_uint (node, "locator_set_index",
3091                               clib_net_to_host_u32 (mp->locator_set_index));
3092
3093   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3094   if (mp->eid_type == 3)
3095     {
3096       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3097       vat_json_init_object (nsh_json);
3098       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3099       vat_json_object_add_uint (nsh_json, "spi",
3100                                 clib_net_to_host_u32 (nsh->spi));
3101       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3102     }
3103   else
3104     {
3105       eid = format (0, "%U", format_lisp_eid_vat,
3106                     mp->eid_type,
3107                     mp->eid,
3108                     mp->eid_prefix_len,
3109                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3110       vec_add1 (eid, 0);
3111       vat_json_object_add_string_copy (node, "eid", eid);
3112       vec_free (eid);
3113     }
3114   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3115   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3116   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3117
3118   if (mp->key_id)
3119     {
3120       vat_json_object_add_uint (node, "key_id",
3121                                 clib_net_to_host_u16 (mp->key_id));
3122       vat_json_object_add_string_copy (node, "key", mp->key);
3123     }
3124 }
3125
3126 static void
3127 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3128 {
3129   vat_main_t *vam = &vat_main;
3130   u8 *seid = 0, *deid = 0;
3131   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3132
3133   deid = format (0, "%U", format_lisp_eid_vat,
3134                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3135
3136   seid = format (0, "%U", format_lisp_eid_vat,
3137                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3138
3139   vec_add1 (deid, 0);
3140   vec_add1 (seid, 0);
3141
3142   if (mp->is_ip4)
3143     format_ip_address_fcn = format_ip4_address;
3144   else
3145     format_ip_address_fcn = format_ip6_address;
3146
3147
3148   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3149          clib_net_to_host_u32 (mp->vni),
3150          seid, deid,
3151          format_ip_address_fcn, mp->lloc,
3152          format_ip_address_fcn, mp->rloc,
3153          clib_net_to_host_u32 (mp->pkt_count),
3154          clib_net_to_host_u32 (mp->bytes));
3155
3156   vec_free (deid);
3157   vec_free (seid);
3158 }
3159
3160 static void
3161 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3162 {
3163   struct in6_addr ip6;
3164   struct in_addr ip4;
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t *node = 0;
3167   u8 *deid = 0, *seid = 0;
3168
3169   if (VAT_JSON_ARRAY != vam->json_tree.type)
3170     {
3171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3172       vat_json_init_array (&vam->json_tree);
3173     }
3174   node = vat_json_array_add (&vam->json_tree);
3175
3176   vat_json_init_object (node);
3177   deid = format (0, "%U", format_lisp_eid_vat,
3178                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3179
3180   seid = format (0, "%U", format_lisp_eid_vat,
3181                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3182
3183   vec_add1 (deid, 0);
3184   vec_add1 (seid, 0);
3185
3186   vat_json_object_add_string_copy (node, "seid", seid);
3187   vat_json_object_add_string_copy (node, "deid", deid);
3188   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3189
3190   if (mp->is_ip4)
3191     {
3192       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3193       vat_json_object_add_ip4 (node, "lloc", ip4);
3194       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3195       vat_json_object_add_ip4 (node, "rloc", ip4);
3196     }
3197   else
3198     {
3199       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3200       vat_json_object_add_ip6 (node, "lloc", ip6);
3201       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3202       vat_json_object_add_ip6 (node, "rloc", ip6);
3203     }
3204   vat_json_object_add_uint (node, "pkt_count",
3205                             clib_net_to_host_u32 (mp->pkt_count));
3206   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3207
3208   vec_free (deid);
3209   vec_free (seid);
3210 }
3211
3212 static void
3213   vl_api_one_eid_table_map_details_t_handler
3214   (vl_api_one_eid_table_map_details_t * mp)
3215 {
3216   vat_main_t *vam = &vat_main;
3217
3218   u8 *line = format (0, "%=10d%=10d",
3219                      clib_net_to_host_u32 (mp->vni),
3220                      clib_net_to_host_u32 (mp->dp_table));
3221   print (vam->ofp, "%v", line);
3222   vec_free (line);
3223 }
3224
3225 static void
3226   vl_api_one_eid_table_map_details_t_handler_json
3227   (vl_api_one_eid_table_map_details_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   vat_json_node_t *node = NULL;
3231
3232   if (VAT_JSON_ARRAY != vam->json_tree.type)
3233     {
3234       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3235       vat_json_init_array (&vam->json_tree);
3236     }
3237   node = vat_json_array_add (&vam->json_tree);
3238   vat_json_init_object (node);
3239   vat_json_object_add_uint (node, "dp_table",
3240                             clib_net_to_host_u32 (mp->dp_table));
3241   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3242 }
3243
3244 static void
3245   vl_api_one_eid_table_vni_details_t_handler
3246   (vl_api_one_eid_table_vni_details_t * mp)
3247 {
3248   vat_main_t *vam = &vat_main;
3249
3250   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3251   print (vam->ofp, "%v", line);
3252   vec_free (line);
3253 }
3254
3255 static void
3256   vl_api_one_eid_table_vni_details_t_handler_json
3257   (vl_api_one_eid_table_vni_details_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   vat_json_node_t *node = NULL;
3261
3262   if (VAT_JSON_ARRAY != vam->json_tree.type)
3263     {
3264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3265       vat_json_init_array (&vam->json_tree);
3266     }
3267   node = vat_json_array_add (&vam->json_tree);
3268   vat_json_init_object (node);
3269   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3270 }
3271
3272 static void
3273   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3274   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3280   print (vam->ofp, "fallback threshold value: %d", mp->value);
3281
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284 }
3285
3286 static void
3287   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3288   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t _node, *node = &_node;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3295   vat_json_init_object (node);
3296   vat_json_object_add_uint (node, "value", mp->value);
3297
3298   vat_json_print (vam->ofp, node);
3299   vat_json_free (node);
3300
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_show_one_map_register_state_reply_t_handler
3307   (vl_api_show_one_map_register_state_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   int retval = clib_net_to_host_u32 (mp->retval);
3311
3312   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3313
3314   vam->retval = retval;
3315   vam->result_ready = 1;
3316 }
3317
3318 static void
3319   vl_api_show_one_map_register_state_reply_t_handler_json
3320   (vl_api_show_one_map_register_state_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t _node, *node = &_node;
3324   int retval = clib_net_to_host_u32 (mp->retval);
3325
3326   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3327
3328   vat_json_init_object (node);
3329   vat_json_object_add_string_copy (node, "state", s);
3330
3331   vat_json_print (vam->ofp, node);
3332   vat_json_free (node);
3333
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336   vec_free (s);
3337 }
3338
3339 static void
3340   vl_api_show_one_rloc_probe_state_reply_t_handler
3341   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3342 {
3343   vat_main_t *vam = &vat_main;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   if (retval)
3347     goto end;
3348
3349   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3350 end:
3351   vam->retval = retval;
3352   vam->result_ready = 1;
3353 }
3354
3355 static void
3356   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3357   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   vat_json_node_t _node, *node = &_node;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3364   vat_json_init_object (node);
3365   vat_json_object_add_string_copy (node, "state", s);
3366
3367   vat_json_print (vam->ofp, node);
3368   vat_json_free (node);
3369
3370   vam->retval = retval;
3371   vam->result_ready = 1;
3372   vec_free (s);
3373 }
3374
3375 static void
3376   vl_api_show_one_stats_enable_disable_reply_t_handler
3377   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   int retval = clib_net_to_host_u32 (mp->retval);
3381
3382   if (retval)
3383     goto end;
3384
3385   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3386 end:
3387   vam->retval = retval;
3388   vam->result_ready = 1;
3389 }
3390
3391 static void
3392   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3393   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   vat_json_node_t _node, *node = &_node;
3397   int retval = clib_net_to_host_u32 (mp->retval);
3398
3399   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3400   vat_json_init_object (node);
3401   vat_json_object_add_string_copy (node, "state", s);
3402
3403   vat_json_print (vam->ofp, node);
3404   vat_json_free (node);
3405
3406   vam->retval = retval;
3407   vam->result_ready = 1;
3408   vec_free (s);
3409 }
3410
3411 static void
3412 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3413 {
3414   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3415   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3416   e->vni = clib_net_to_host_u32 (e->vni);
3417 }
3418
3419 static void
3420   gpe_fwd_entries_get_reply_t_net_to_host
3421   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3422 {
3423   u32 i;
3424
3425   mp->count = clib_net_to_host_u32 (mp->count);
3426   for (i = 0; i < mp->count; i++)
3427     {
3428       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3429     }
3430 }
3431
3432 static u8 *
3433 format_gpe_encap_mode (u8 * s, va_list * args)
3434 {
3435   u32 mode = va_arg (*args, u32);
3436
3437   switch (mode)
3438     {
3439     case 0:
3440       return format (s, "lisp");
3441     case 1:
3442       return format (s, "vxlan");
3443     }
3444   return 0;
3445 }
3446
3447 static void
3448   vl_api_gpe_get_encap_mode_reply_t_handler
3449   (vl_api_gpe_get_encap_mode_reply_t * mp)
3450 {
3451   vat_main_t *vam = &vat_main;
3452
3453   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void
3459   vl_api_gpe_get_encap_mode_reply_t_handler_json
3460   (vl_api_gpe_get_encap_mode_reply_t * mp)
3461 {
3462   vat_main_t *vam = &vat_main;
3463   vat_json_node_t node;
3464
3465   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3466   vec_add1 (encap_mode, 0);
3467
3468   vat_json_init_object (&node);
3469   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3470
3471   vec_free (encap_mode);
3472   vat_json_print (vam->ofp, &node);
3473   vat_json_free (&node);
3474
3475   vam->retval = ntohl (mp->retval);
3476   vam->result_ready = 1;
3477 }
3478
3479 static void
3480   vl_api_gpe_fwd_entry_path_details_t_handler
3481   (vl_api_gpe_fwd_entry_path_details_t * mp)
3482 {
3483   vat_main_t *vam = &vat_main;
3484   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3485
3486   if (mp->lcl_loc.is_ip4)
3487     format_ip_address_fcn = format_ip4_address;
3488   else
3489     format_ip_address_fcn = format_ip6_address;
3490
3491   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3492          format_ip_address_fcn, &mp->lcl_loc,
3493          format_ip_address_fcn, &mp->rmt_loc);
3494 }
3495
3496 static void
3497 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3498 {
3499   struct in6_addr ip6;
3500   struct in_addr ip4;
3501
3502   if (loc->is_ip4)
3503     {
3504       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3505       vat_json_object_add_ip4 (n, "address", ip4);
3506     }
3507   else
3508     {
3509       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3510       vat_json_object_add_ip6 (n, "address", ip6);
3511     }
3512   vat_json_object_add_uint (n, "weight", loc->weight);
3513 }
3514
3515 static void
3516   vl_api_gpe_fwd_entry_path_details_t_handler_json
3517   (vl_api_gpe_fwd_entry_path_details_t * mp)
3518 {
3519   vat_main_t *vam = &vat_main;
3520   vat_json_node_t *node = NULL;
3521   vat_json_node_t *loc_node;
3522
3523   if (VAT_JSON_ARRAY != vam->json_tree.type)
3524     {
3525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3526       vat_json_init_array (&vam->json_tree);
3527     }
3528   node = vat_json_array_add (&vam->json_tree);
3529   vat_json_init_object (node);
3530
3531   loc_node = vat_json_object_add (node, "local_locator");
3532   vat_json_init_object (loc_node);
3533   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3534
3535   loc_node = vat_json_object_add (node, "remote_locator");
3536   vat_json_init_object (loc_node);
3537   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3538 }
3539
3540 static void
3541   vl_api_gpe_fwd_entries_get_reply_t_handler
3542   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3543 {
3544   vat_main_t *vam = &vat_main;
3545   u32 i;
3546   int retval = clib_net_to_host_u32 (mp->retval);
3547   vl_api_gpe_fwd_entry_t *e;
3548
3549   if (retval)
3550     goto end;
3551
3552   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3553
3554   for (i = 0; i < mp->count; i++)
3555     {
3556       e = &mp->entries[i];
3557       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3558              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3559              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3560     }
3561
3562 end:
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3569   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3570 {
3571   u8 *s = 0;
3572   vat_main_t *vam = &vat_main;
3573   vat_json_node_t *e = 0, root;
3574   u32 i;
3575   int retval = clib_net_to_host_u32 (mp->retval);
3576   vl_api_gpe_fwd_entry_t *fwd;
3577
3578   if (retval)
3579     goto end;
3580
3581   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3582   vat_json_init_array (&root);
3583
3584   for (i = 0; i < mp->count; i++)
3585     {
3586       e = vat_json_array_add (&root);
3587       fwd = &mp->entries[i];
3588
3589       vat_json_init_object (e);
3590       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3591       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3592       vat_json_object_add_int (e, "vni", fwd->vni);
3593       vat_json_object_add_int (e, "action", fwd->action);
3594
3595       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3596                   fwd->leid_prefix_len);
3597       vec_add1 (s, 0);
3598       vat_json_object_add_string_copy (e, "leid", s);
3599       vec_free (s);
3600
3601       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3602                   fwd->reid_prefix_len);
3603       vec_add1 (s, 0);
3604       vat_json_object_add_string_copy (e, "reid", s);
3605       vec_free (s);
3606     }
3607
3608   vat_json_print (vam->ofp, &root);
3609   vat_json_free (&root);
3610
3611 end:
3612   vam->retval = retval;
3613   vam->result_ready = 1;
3614 }
3615
3616 static void
3617   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3618   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3619 {
3620   vat_main_t *vam = &vat_main;
3621   u32 i, n;
3622   int retval = clib_net_to_host_u32 (mp->retval);
3623   vl_api_gpe_native_fwd_rpath_t *r;
3624
3625   if (retval)
3626     goto end;
3627
3628   n = clib_net_to_host_u32 (mp->count);
3629
3630   for (i = 0; i < n; i++)
3631     {
3632       r = &mp->entries[i];
3633       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3634              clib_net_to_host_u32 (r->fib_index),
3635              clib_net_to_host_u32 (r->nh_sw_if_index),
3636              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3637     }
3638
3639 end:
3640   vam->retval = retval;
3641   vam->result_ready = 1;
3642 }
3643
3644 static void
3645   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3646   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3647 {
3648   vat_main_t *vam = &vat_main;
3649   vat_json_node_t root, *e;
3650   u32 i, n;
3651   int retval = clib_net_to_host_u32 (mp->retval);
3652   vl_api_gpe_native_fwd_rpath_t *r;
3653   u8 *s;
3654
3655   if (retval)
3656     goto end;
3657
3658   n = clib_net_to_host_u32 (mp->count);
3659   vat_json_init_array (&root);
3660
3661   for (i = 0; i < n; i++)
3662     {
3663       e = vat_json_array_add (&root);
3664       vat_json_init_object (e);
3665       r = &mp->entries[i];
3666       s =
3667         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3668                 r->nh_addr);
3669       vec_add1 (s, 0);
3670       vat_json_object_add_string_copy (e, "ip4", s);
3671       vec_free (s);
3672
3673       vat_json_object_add_uint (e, "fib_index",
3674                                 clib_net_to_host_u32 (r->fib_index));
3675       vat_json_object_add_uint (e, "nh_sw_if_index",
3676                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3677     }
3678
3679   vat_json_print (vam->ofp, &root);
3680   vat_json_free (&root);
3681
3682 end:
3683   vam->retval = retval;
3684   vam->result_ready = 1;
3685 }
3686
3687 static void
3688   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3689   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3690 {
3691   vat_main_t *vam = &vat_main;
3692   u32 i, n;
3693   int retval = clib_net_to_host_u32 (mp->retval);
3694
3695   if (retval)
3696     goto end;
3697
3698   n = clib_net_to_host_u32 (mp->count);
3699
3700   for (i = 0; i < n; i++)
3701     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3710   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   vat_json_node_t root;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716
3717   if (retval)
3718     goto end;
3719
3720   n = clib_net_to_host_u32 (mp->count);
3721   vat_json_init_array (&root);
3722
3723   for (i = 0; i < n; i++)
3724     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3725
3726   vat_json_print (vam->ofp, &root);
3727   vat_json_free (&root);
3728
3729 end:
3730   vam->retval = retval;
3731   vam->result_ready = 1;
3732 }
3733
3734 static void
3735   vl_api_one_ndp_entries_get_reply_t_handler
3736   (vl_api_one_ndp_entries_get_reply_t * mp)
3737 {
3738   vat_main_t *vam = &vat_main;
3739   u32 i, n;
3740   int retval = clib_net_to_host_u32 (mp->retval);
3741
3742   if (retval)
3743     goto end;
3744
3745   n = clib_net_to_host_u32 (mp->count);
3746
3747   for (i = 0; i < n; i++)
3748     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3749            format_ethernet_address, mp->entries[i].mac);
3750
3751 end:
3752   vam->retval = retval;
3753   vam->result_ready = 1;
3754 }
3755
3756 static void
3757   vl_api_one_ndp_entries_get_reply_t_handler_json
3758   (vl_api_one_ndp_entries_get_reply_t * mp)
3759 {
3760   u8 *s = 0;
3761   vat_main_t *vam = &vat_main;
3762   vat_json_node_t *e = 0, root;
3763   u32 i, n;
3764   int retval = clib_net_to_host_u32 (mp->retval);
3765   vl_api_one_ndp_entry_t *arp_entry;
3766
3767   if (retval)
3768     goto end;
3769
3770   n = clib_net_to_host_u32 (mp->count);
3771   vat_json_init_array (&root);
3772
3773   for (i = 0; i < n; i++)
3774     {
3775       e = vat_json_array_add (&root);
3776       arp_entry = &mp->entries[i];
3777
3778       vat_json_init_object (e);
3779       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3780       vec_add1 (s, 0);
3781
3782       vat_json_object_add_string_copy (e, "mac", s);
3783       vec_free (s);
3784
3785       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3786       vec_add1 (s, 0);
3787       vat_json_object_add_string_copy (e, "ip6", s);
3788       vec_free (s);
3789     }
3790
3791   vat_json_print (vam->ofp, &root);
3792   vat_json_free (&root);
3793
3794 end:
3795   vam->retval = retval;
3796   vam->result_ready = 1;
3797 }
3798
3799 static void
3800   vl_api_one_l2_arp_entries_get_reply_t_handler
3801   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3802 {
3803   vat_main_t *vam = &vat_main;
3804   u32 i, n;
3805   int retval = clib_net_to_host_u32 (mp->retval);
3806
3807   if (retval)
3808     goto end;
3809
3810   n = clib_net_to_host_u32 (mp->count);
3811
3812   for (i = 0; i < n; i++)
3813     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3814            format_ethernet_address, mp->entries[i].mac);
3815
3816 end:
3817   vam->retval = retval;
3818   vam->result_ready = 1;
3819 }
3820
3821 static void
3822   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3823   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3824 {
3825   u8 *s = 0;
3826   vat_main_t *vam = &vat_main;
3827   vat_json_node_t *e = 0, root;
3828   u32 i, n;
3829   int retval = clib_net_to_host_u32 (mp->retval);
3830   vl_api_one_l2_arp_entry_t *arp_entry;
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836   vat_json_init_array (&root);
3837
3838   for (i = 0; i < n; i++)
3839     {
3840       e = vat_json_array_add (&root);
3841       arp_entry = &mp->entries[i];
3842
3843       vat_json_init_object (e);
3844       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3845       vec_add1 (s, 0);
3846
3847       vat_json_object_add_string_copy (e, "mac", s);
3848       vec_free (s);
3849
3850       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3851       vec_add1 (s, 0);
3852       vat_json_object_add_string_copy (e, "ip4", s);
3853       vec_free (s);
3854     }
3855
3856   vat_json_print (vam->ofp, &root);
3857   vat_json_free (&root);
3858
3859 end:
3860   vam->retval = retval;
3861   vam->result_ready = 1;
3862 }
3863
3864 static void
3865 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3866 {
3867   vat_main_t *vam = &vat_main;
3868   u32 i, n;
3869   int retval = clib_net_to_host_u32 (mp->retval);
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875
3876   for (i = 0; i < n; i++)
3877     {
3878       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3879     }
3880
3881 end:
3882   vam->retval = retval;
3883   vam->result_ready = 1;
3884 }
3885
3886 static void
3887   vl_api_one_ndp_bd_get_reply_t_handler_json
3888   (vl_api_one_ndp_bd_get_reply_t * mp)
3889 {
3890   vat_main_t *vam = &vat_main;
3891   vat_json_node_t root;
3892   u32 i, n;
3893   int retval = clib_net_to_host_u32 (mp->retval);
3894
3895   if (retval)
3896     goto end;
3897
3898   n = clib_net_to_host_u32 (mp->count);
3899   vat_json_init_array (&root);
3900
3901   for (i = 0; i < n; i++)
3902     {
3903       vat_json_array_add_uint (&root,
3904                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_l2_arp_bd_get_reply_t_handler
3917   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3918 {
3919   vat_main_t *vam = &vat_main;
3920   u32 i, n;
3921   int retval = clib_net_to_host_u32 (mp->retval);
3922
3923   if (retval)
3924     goto end;
3925
3926   n = clib_net_to_host_u32 (mp->count);
3927
3928   for (i = 0; i < n; i++)
3929     {
3930       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3931     }
3932
3933 end:
3934   vam->retval = retval;
3935   vam->result_ready = 1;
3936 }
3937
3938 static void
3939   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3940   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3941 {
3942   vat_main_t *vam = &vat_main;
3943   vat_json_node_t root;
3944   u32 i, n;
3945   int retval = clib_net_to_host_u32 (mp->retval);
3946
3947   if (retval)
3948     goto end;
3949
3950   n = clib_net_to_host_u32 (mp->count);
3951   vat_json_init_array (&root);
3952
3953   for (i = 0; i < n; i++)
3954     {
3955       vat_json_array_add_uint (&root,
3956                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_adjacencies_get_reply_t_handler
3969   (vl_api_one_adjacencies_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974   vl_api_one_adjacency_t *a;
3975
3976   if (retval)
3977     goto end;
3978
3979   n = clib_net_to_host_u32 (mp->count);
3980
3981   for (i = 0; i < n; i++)
3982     {
3983       a = &mp->adjacencies[i];
3984       print (vam->ofp, "%U %40U",
3985              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3986              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3987     }
3988
3989 end:
3990   vam->retval = retval;
3991   vam->result_ready = 1;
3992 }
3993
3994 static void
3995   vl_api_one_adjacencies_get_reply_t_handler_json
3996   (vl_api_one_adjacencies_get_reply_t * mp)
3997 {
3998   u8 *s = 0;
3999   vat_main_t *vam = &vat_main;
4000   vat_json_node_t *e = 0, root;
4001   u32 i, n;
4002   int retval = clib_net_to_host_u32 (mp->retval);
4003   vl_api_one_adjacency_t *a;
4004
4005   if (retval)
4006     goto end;
4007
4008   n = clib_net_to_host_u32 (mp->count);
4009   vat_json_init_array (&root);
4010
4011   for (i = 0; i < n; i++)
4012     {
4013       e = vat_json_array_add (&root);
4014       a = &mp->adjacencies[i];
4015
4016       vat_json_init_object (e);
4017       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4018                   a->leid_prefix_len);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "leid", s);
4021       vec_free (s);
4022
4023       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4024                   a->reid_prefix_len);
4025       vec_add1 (s, 0);
4026       vat_json_object_add_string_copy (e, "reid", s);
4027       vec_free (s);
4028     }
4029
4030   vat_json_print (vam->ofp, &root);
4031   vat_json_free (&root);
4032
4033 end:
4034   vam->retval = retval;
4035   vam->result_ready = 1;
4036 }
4037
4038 static void
4039 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4040 {
4041   vat_main_t *vam = &vat_main;
4042
4043   print (vam->ofp, "%=20U",
4044          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4045          mp->ip_address);
4046 }
4047
4048 static void
4049   vl_api_one_map_server_details_t_handler_json
4050   (vl_api_one_map_server_details_t * mp)
4051 {
4052   vat_main_t *vam = &vat_main;
4053   vat_json_node_t *node = NULL;
4054   struct in6_addr ip6;
4055   struct in_addr ip4;
4056
4057   if (VAT_JSON_ARRAY != vam->json_tree.type)
4058     {
4059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4060       vat_json_init_array (&vam->json_tree);
4061     }
4062   node = vat_json_array_add (&vam->json_tree);
4063
4064   vat_json_init_object (node);
4065   if (mp->is_ipv6)
4066     {
4067       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4068       vat_json_object_add_ip6 (node, "map-server", ip6);
4069     }
4070   else
4071     {
4072       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4073       vat_json_object_add_ip4 (node, "map-server", ip4);
4074     }
4075 }
4076
4077 static void
4078 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4079                                            * mp)
4080 {
4081   vat_main_t *vam = &vat_main;
4082
4083   print (vam->ofp, "%=20U",
4084          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4085          mp->ip_address);
4086 }
4087
4088 static void
4089   vl_api_one_map_resolver_details_t_handler_json
4090   (vl_api_one_map_resolver_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   vat_json_node_t *node = NULL;
4094   struct in6_addr ip6;
4095   struct in_addr ip4;
4096
4097   if (VAT_JSON_ARRAY != vam->json_tree.type)
4098     {
4099       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4100       vat_json_init_array (&vam->json_tree);
4101     }
4102   node = vat_json_array_add (&vam->json_tree);
4103
4104   vat_json_init_object (node);
4105   if (mp->is_ipv6)
4106     {
4107       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4108       vat_json_object_add_ip6 (node, "map resolver", ip6);
4109     }
4110   else
4111     {
4112       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4113       vat_json_object_add_ip4 (node, "map resolver", ip4);
4114     }
4115 }
4116
4117 static void
4118 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   i32 retval = ntohl (mp->retval);
4122
4123   if (0 <= retval)
4124     {
4125       print (vam->ofp, "feature: %s\ngpe: %s",
4126              mp->feature_status ? "enabled" : "disabled",
4127              mp->gpe_status ? "enabled" : "disabled");
4128     }
4129
4130   vam->retval = retval;
4131   vam->result_ready = 1;
4132 }
4133
4134 static void
4135   vl_api_show_one_status_reply_t_handler_json
4136   (vl_api_show_one_status_reply_t * mp)
4137 {
4138   vat_main_t *vam = &vat_main;
4139   vat_json_node_t node;
4140   u8 *gpe_status = NULL;
4141   u8 *feature_status = NULL;
4142
4143   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4144   feature_status = format (0, "%s",
4145                            mp->feature_status ? "enabled" : "disabled");
4146   vec_add1 (gpe_status, 0);
4147   vec_add1 (feature_status, 0);
4148
4149   vat_json_init_object (&node);
4150   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4151   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4152
4153   vec_free (gpe_status);
4154   vec_free (feature_status);
4155
4156   vat_json_print (vam->ofp, &node);
4157   vat_json_free (&node);
4158
4159   vam->retval = ntohl (mp->retval);
4160   vam->result_ready = 1;
4161 }
4162
4163 static void
4164   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4165   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4166 {
4167   vat_main_t *vam = &vat_main;
4168   i32 retval = ntohl (mp->retval);
4169
4170   if (retval >= 0)
4171     {
4172       print (vam->ofp, "%=20s", mp->locator_set_name);
4173     }
4174
4175   vam->retval = retval;
4176   vam->result_ready = 1;
4177 }
4178
4179 static void
4180   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4181   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4182 {
4183   vat_main_t *vam = &vat_main;
4184   vat_json_node_t *node = NULL;
4185
4186   if (VAT_JSON_ARRAY != vam->json_tree.type)
4187     {
4188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4189       vat_json_init_array (&vam->json_tree);
4190     }
4191   node = vat_json_array_add (&vam->json_tree);
4192
4193   vat_json_init_object (node);
4194   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4195
4196   vat_json_print (vam->ofp, node);
4197   vat_json_free (node);
4198
4199   vam->retval = ntohl (mp->retval);
4200   vam->result_ready = 1;
4201 }
4202
4203 static u8 *
4204 format_lisp_map_request_mode (u8 * s, va_list * args)
4205 {
4206   u32 mode = va_arg (*args, u32);
4207
4208   switch (mode)
4209     {
4210     case 0:
4211       return format (0, "dst-only");
4212     case 1:
4213       return format (0, "src-dst");
4214     }
4215   return 0;
4216 }
4217
4218 static void
4219   vl_api_show_one_map_request_mode_reply_t_handler
4220   (vl_api_show_one_map_request_mode_reply_t * mp)
4221 {
4222   vat_main_t *vam = &vat_main;
4223   i32 retval = ntohl (mp->retval);
4224
4225   if (0 <= retval)
4226     {
4227       u32 mode = mp->mode;
4228       print (vam->ofp, "map_request_mode: %U",
4229              format_lisp_map_request_mode, mode);
4230     }
4231
4232   vam->retval = retval;
4233   vam->result_ready = 1;
4234 }
4235
4236 static void
4237   vl_api_show_one_map_request_mode_reply_t_handler_json
4238   (vl_api_show_one_map_request_mode_reply_t * mp)
4239 {
4240   vat_main_t *vam = &vat_main;
4241   vat_json_node_t node;
4242   u8 *s = 0;
4243   u32 mode;
4244
4245   mode = mp->mode;
4246   s = format (0, "%U", format_lisp_map_request_mode, mode);
4247   vec_add1 (s, 0);
4248
4249   vat_json_init_object (&node);
4250   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4251   vat_json_print (vam->ofp, &node);
4252   vat_json_free (&node);
4253
4254   vec_free (s);
4255   vam->retval = ntohl (mp->retval);
4256   vam->result_ready = 1;
4257 }
4258
4259 static void
4260   vl_api_one_show_xtr_mode_reply_t_handler
4261   (vl_api_one_show_xtr_mode_reply_t * mp)
4262 {
4263   vat_main_t *vam = &vat_main;
4264   i32 retval = ntohl (mp->retval);
4265
4266   if (0 <= retval)
4267     {
4268       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4269     }
4270
4271   vam->retval = retval;
4272   vam->result_ready = 1;
4273 }
4274
4275 static void
4276   vl_api_one_show_xtr_mode_reply_t_handler_json
4277   (vl_api_one_show_xtr_mode_reply_t * mp)
4278 {
4279   vat_main_t *vam = &vat_main;
4280   vat_json_node_t node;
4281   u8 *status = 0;
4282
4283   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4284   vec_add1 (status, 0);
4285
4286   vat_json_init_object (&node);
4287   vat_json_object_add_string_copy (&node, "status", status);
4288
4289   vec_free (status);
4290
4291   vat_json_print (vam->ofp, &node);
4292   vat_json_free (&node);
4293
4294   vam->retval = ntohl (mp->retval);
4295   vam->result_ready = 1;
4296 }
4297
4298 static void
4299   vl_api_one_show_pitr_mode_reply_t_handler
4300   (vl_api_one_show_pitr_mode_reply_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303   i32 retval = ntohl (mp->retval);
4304
4305   if (0 <= retval)
4306     {
4307       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4308     }
4309
4310   vam->retval = retval;
4311   vam->result_ready = 1;
4312 }
4313
4314 static void
4315   vl_api_one_show_pitr_mode_reply_t_handler_json
4316   (vl_api_one_show_pitr_mode_reply_t * mp)
4317 {
4318   vat_main_t *vam = &vat_main;
4319   vat_json_node_t node;
4320   u8 *status = 0;
4321
4322   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4323   vec_add1 (status, 0);
4324
4325   vat_json_init_object (&node);
4326   vat_json_object_add_string_copy (&node, "status", status);
4327
4328   vec_free (status);
4329
4330   vat_json_print (vam->ofp, &node);
4331   vat_json_free (&node);
4332
4333   vam->retval = ntohl (mp->retval);
4334   vam->result_ready = 1;
4335 }
4336
4337 static void
4338   vl_api_one_show_petr_mode_reply_t_handler
4339   (vl_api_one_show_petr_mode_reply_t * mp)
4340 {
4341   vat_main_t *vam = &vat_main;
4342   i32 retval = ntohl (mp->retval);
4343
4344   if (0 <= retval)
4345     {
4346       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4347     }
4348
4349   vam->retval = retval;
4350   vam->result_ready = 1;
4351 }
4352
4353 static void
4354   vl_api_one_show_petr_mode_reply_t_handler_json
4355   (vl_api_one_show_petr_mode_reply_t * mp)
4356 {
4357   vat_main_t *vam = &vat_main;
4358   vat_json_node_t node;
4359   u8 *status = 0;
4360
4361   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4362   vec_add1 (status, 0);
4363
4364   vat_json_init_object (&node);
4365   vat_json_object_add_string_copy (&node, "status", status);
4366
4367   vec_free (status);
4368
4369   vat_json_print (vam->ofp, &node);
4370   vat_json_free (&node);
4371
4372   vam->retval = ntohl (mp->retval);
4373   vam->result_ready = 1;
4374 }
4375
4376 static void
4377   vl_api_show_one_use_petr_reply_t_handler
4378   (vl_api_show_one_use_petr_reply_t * mp)
4379 {
4380   vat_main_t *vam = &vat_main;
4381   i32 retval = ntohl (mp->retval);
4382
4383   if (0 <= retval)
4384     {
4385       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4386       if (mp->status)
4387         {
4388           print (vam->ofp, "Proxy-ETR address; %U",
4389                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4390                  mp->address);
4391         }
4392     }
4393
4394   vam->retval = retval;
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399   vl_api_show_one_use_petr_reply_t_handler_json
4400   (vl_api_show_one_use_petr_reply_t * mp)
4401 {
4402   vat_main_t *vam = &vat_main;
4403   vat_json_node_t node;
4404   u8 *status = 0;
4405   struct in_addr ip4;
4406   struct in6_addr ip6;
4407
4408   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4409   vec_add1 (status, 0);
4410
4411   vat_json_init_object (&node);
4412   vat_json_object_add_string_copy (&node, "status", status);
4413   if (mp->status)
4414     {
4415       if (mp->is_ip4)
4416         {
4417           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4418           vat_json_object_add_ip6 (&node, "address", ip6);
4419         }
4420       else
4421         {
4422           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4423           vat_json_object_add_ip4 (&node, "address", ip4);
4424         }
4425     }
4426
4427   vec_free (status);
4428
4429   vat_json_print (vam->ofp, &node);
4430   vat_json_free (&node);
4431
4432   vam->retval = ntohl (mp->retval);
4433   vam->result_ready = 1;
4434 }
4435
4436 static void
4437   vl_api_show_one_nsh_mapping_reply_t_handler
4438   (vl_api_show_one_nsh_mapping_reply_t * mp)
4439 {
4440   vat_main_t *vam = &vat_main;
4441   i32 retval = ntohl (mp->retval);
4442
4443   if (0 <= retval)
4444     {
4445       print (vam->ofp, "%-20s%-16s",
4446              mp->is_set ? "set" : "not-set",
4447              mp->is_set ? (char *) mp->locator_set_name : "");
4448     }
4449
4450   vam->retval = retval;
4451   vam->result_ready = 1;
4452 }
4453
4454 static void
4455   vl_api_show_one_nsh_mapping_reply_t_handler_json
4456   (vl_api_show_one_nsh_mapping_reply_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459   vat_json_node_t node;
4460   u8 *status = 0;
4461
4462   status = format (0, "%s", mp->is_set ? "yes" : "no");
4463   vec_add1 (status, 0);
4464
4465   vat_json_init_object (&node);
4466   vat_json_object_add_string_copy (&node, "is_set", status);
4467   if (mp->is_set)
4468     {
4469       vat_json_object_add_string_copy (&node, "locator_set",
4470                                        mp->locator_set_name);
4471     }
4472
4473   vec_free (status);
4474
4475   vat_json_print (vam->ofp, &node);
4476   vat_json_free (&node);
4477
4478   vam->retval = ntohl (mp->retval);
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_show_one_map_register_ttl_reply_t_handler
4484   (vl_api_show_one_map_register_ttl_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   i32 retval = ntohl (mp->retval);
4488
4489   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4490
4491   if (0 <= retval)
4492     {
4493       print (vam->ofp, "ttl: %u", mp->ttl);
4494     }
4495
4496   vam->retval = retval;
4497   vam->result_ready = 1;
4498 }
4499
4500 static void
4501   vl_api_show_one_map_register_ttl_reply_t_handler_json
4502   (vl_api_show_one_map_register_ttl_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   vat_json_node_t node;
4506
4507   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4508   vat_json_init_object (&node);
4509   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4510
4511   vat_json_print (vam->ofp, &node);
4512   vat_json_free (&node);
4513
4514   vam->retval = ntohl (mp->retval);
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4520 {
4521   vat_main_t *vam = &vat_main;
4522   i32 retval = ntohl (mp->retval);
4523
4524   if (0 <= retval)
4525     {
4526       print (vam->ofp, "%-20s%-16s",
4527              mp->status ? "enabled" : "disabled",
4528              mp->status ? (char *) mp->locator_set_name : "");
4529     }
4530
4531   vam->retval = retval;
4532   vam->result_ready = 1;
4533 }
4534
4535 static void
4536 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4537 {
4538   vat_main_t *vam = &vat_main;
4539   vat_json_node_t node;
4540   u8 *status = 0;
4541
4542   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4543   vec_add1 (status, 0);
4544
4545   vat_json_init_object (&node);
4546   vat_json_object_add_string_copy (&node, "status", status);
4547   if (mp->status)
4548     {
4549       vat_json_object_add_string_copy (&node, "locator_set",
4550                                        mp->locator_set_name);
4551     }
4552
4553   vec_free (status);
4554
4555   vat_json_print (vam->ofp, &node);
4556   vat_json_free (&node);
4557
4558   vam->retval = ntohl (mp->retval);
4559   vam->result_ready = 1;
4560 }
4561
4562 static u8 *
4563 format_policer_type (u8 * s, va_list * va)
4564 {
4565   u32 i = va_arg (*va, u32);
4566
4567   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4568     s = format (s, "1r2c");
4569   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4570     s = format (s, "1r3c");
4571   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4572     s = format (s, "2r3c-2698");
4573   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4574     s = format (s, "2r3c-4115");
4575   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4576     s = format (s, "2r3c-mef5cf1");
4577   else
4578     s = format (s, "ILLEGAL");
4579   return s;
4580 }
4581
4582 static u8 *
4583 format_policer_rate_type (u8 * s, va_list * va)
4584 {
4585   u32 i = va_arg (*va, u32);
4586
4587   if (i == SSE2_QOS_RATE_KBPS)
4588     s = format (s, "kbps");
4589   else if (i == SSE2_QOS_RATE_PPS)
4590     s = format (s, "pps");
4591   else
4592     s = format (s, "ILLEGAL");
4593   return s;
4594 }
4595
4596 static u8 *
4597 format_policer_round_type (u8 * s, va_list * va)
4598 {
4599   u32 i = va_arg (*va, u32);
4600
4601   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4602     s = format (s, "closest");
4603   else if (i == SSE2_QOS_ROUND_TO_UP)
4604     s = format (s, "up");
4605   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4606     s = format (s, "down");
4607   else
4608     s = format (s, "ILLEGAL");
4609   return s;
4610 }
4611
4612 static u8 *
4613 format_policer_action_type (u8 * s, va_list * va)
4614 {
4615   u32 i = va_arg (*va, u32);
4616
4617   if (i == SSE2_QOS_ACTION_DROP)
4618     s = format (s, "drop");
4619   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4620     s = format (s, "transmit");
4621   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4622     s = format (s, "mark-and-transmit");
4623   else
4624     s = format (s, "ILLEGAL");
4625   return s;
4626 }
4627
4628 static u8 *
4629 format_dscp (u8 * s, va_list * va)
4630 {
4631   u32 i = va_arg (*va, u32);
4632   char *t = 0;
4633
4634   switch (i)
4635     {
4636 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4637       foreach_vnet_dscp
4638 #undef _
4639     default:
4640       return format (s, "ILLEGAL");
4641     }
4642   s = format (s, "%s", t);
4643   return s;
4644 }
4645
4646 static void
4647 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4648 {
4649   vat_main_t *vam = &vat_main;
4650   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4651
4652   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4653     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4654   else
4655     conform_dscp_str = format (0, "");
4656
4657   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4658     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4659   else
4660     exceed_dscp_str = format (0, "");
4661
4662   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4663     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4664   else
4665     violate_dscp_str = format (0, "");
4666
4667   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4668          "rate type %U, round type %U, %s rate, %s color-aware, "
4669          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4670          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4671          "conform action %U%s, exceed action %U%s, violate action %U%s",
4672          mp->name,
4673          format_policer_type, mp->type,
4674          ntohl (mp->cir),
4675          ntohl (mp->eir),
4676          clib_net_to_host_u64 (mp->cb),
4677          clib_net_to_host_u64 (mp->eb),
4678          format_policer_rate_type, mp->rate_type,
4679          format_policer_round_type, mp->round_type,
4680          mp->single_rate ? "single" : "dual",
4681          mp->color_aware ? "is" : "not",
4682          ntohl (mp->cir_tokens_per_period),
4683          ntohl (mp->pir_tokens_per_period),
4684          ntohl (mp->scale),
4685          ntohl (mp->current_limit),
4686          ntohl (mp->current_bucket),
4687          ntohl (mp->extended_limit),
4688          ntohl (mp->extended_bucket),
4689          clib_net_to_host_u64 (mp->last_update_time),
4690          format_policer_action_type, mp->conform_action_type,
4691          conform_dscp_str,
4692          format_policer_action_type, mp->exceed_action_type,
4693          exceed_dscp_str,
4694          format_policer_action_type, mp->violate_action_type,
4695          violate_dscp_str);
4696
4697   vec_free (conform_dscp_str);
4698   vec_free (exceed_dscp_str);
4699   vec_free (violate_dscp_str);
4700 }
4701
4702 static void vl_api_policer_details_t_handler_json
4703   (vl_api_policer_details_t * mp)
4704 {
4705   vat_main_t *vam = &vat_main;
4706   vat_json_node_t *node;
4707   u8 *rate_type_str, *round_type_str, *type_str;
4708   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4709
4710   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4711   round_type_str =
4712     format (0, "%U", format_policer_round_type, mp->round_type);
4713   type_str = format (0, "%U", format_policer_type, mp->type);
4714   conform_action_str = format (0, "%U", format_policer_action_type,
4715                                mp->conform_action_type);
4716   exceed_action_str = format (0, "%U", format_policer_action_type,
4717                               mp->exceed_action_type);
4718   violate_action_str = format (0, "%U", format_policer_action_type,
4719                                mp->violate_action_type);
4720
4721   if (VAT_JSON_ARRAY != vam->json_tree.type)
4722     {
4723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4724       vat_json_init_array (&vam->json_tree);
4725     }
4726   node = vat_json_array_add (&vam->json_tree);
4727
4728   vat_json_init_object (node);
4729   vat_json_object_add_string_copy (node, "name", mp->name);
4730   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4731   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4732   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4733   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4734   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4735   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4736   vat_json_object_add_string_copy (node, "type", type_str);
4737   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4738   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4739   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4740   vat_json_object_add_uint (node, "cir_tokens_per_period",
4741                             ntohl (mp->cir_tokens_per_period));
4742   vat_json_object_add_uint (node, "eir_tokens_per_period",
4743                             ntohl (mp->pir_tokens_per_period));
4744   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4745   vat_json_object_add_uint (node, "current_bucket",
4746                             ntohl (mp->current_bucket));
4747   vat_json_object_add_uint (node, "extended_limit",
4748                             ntohl (mp->extended_limit));
4749   vat_json_object_add_uint (node, "extended_bucket",
4750                             ntohl (mp->extended_bucket));
4751   vat_json_object_add_uint (node, "last_update_time",
4752                             ntohl (mp->last_update_time));
4753   vat_json_object_add_string_copy (node, "conform_action",
4754                                    conform_action_str);
4755   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4756     {
4757       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4758       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4759       vec_free (dscp_str);
4760     }
4761   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4762   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4763     {
4764       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4765       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4766       vec_free (dscp_str);
4767     }
4768   vat_json_object_add_string_copy (node, "violate_action",
4769                                    violate_action_str);
4770   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4771     {
4772       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4773       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4774       vec_free (dscp_str);
4775     }
4776
4777   vec_free (rate_type_str);
4778   vec_free (round_type_str);
4779   vec_free (type_str);
4780   vec_free (conform_action_str);
4781   vec_free (exceed_action_str);
4782   vec_free (violate_action_str);
4783 }
4784
4785 static void
4786 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4787                                            mp)
4788 {
4789   vat_main_t *vam = &vat_main;
4790   int i, count = ntohl (mp->count);
4791
4792   if (count > 0)
4793     print (vam->ofp, "classify table ids (%d) : ", count);
4794   for (i = 0; i < count; i++)
4795     {
4796       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4797       print (vam->ofp, (i < count - 1) ? "," : "");
4798     }
4799   vam->retval = ntohl (mp->retval);
4800   vam->result_ready = 1;
4801 }
4802
4803 static void
4804   vl_api_classify_table_ids_reply_t_handler_json
4805   (vl_api_classify_table_ids_reply_t * mp)
4806 {
4807   vat_main_t *vam = &vat_main;
4808   int i, count = ntohl (mp->count);
4809
4810   if (count > 0)
4811     {
4812       vat_json_node_t node;
4813
4814       vat_json_init_object (&node);
4815       for (i = 0; i < count; i++)
4816         {
4817           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4818         }
4819       vat_json_print (vam->ofp, &node);
4820       vat_json_free (&node);
4821     }
4822   vam->retval = ntohl (mp->retval);
4823   vam->result_ready = 1;
4824 }
4825
4826 static void
4827   vl_api_classify_table_by_interface_reply_t_handler
4828   (vl_api_classify_table_by_interface_reply_t * mp)
4829 {
4830   vat_main_t *vam = &vat_main;
4831   u32 table_id;
4832
4833   table_id = ntohl (mp->l2_table_id);
4834   if (table_id != ~0)
4835     print (vam->ofp, "l2 table id : %d", table_id);
4836   else
4837     print (vam->ofp, "l2 table id : No input ACL tables configured");
4838   table_id = ntohl (mp->ip4_table_id);
4839   if (table_id != ~0)
4840     print (vam->ofp, "ip4 table id : %d", table_id);
4841   else
4842     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4843   table_id = ntohl (mp->ip6_table_id);
4844   if (table_id != ~0)
4845     print (vam->ofp, "ip6 table id : %d", table_id);
4846   else
4847     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4848   vam->retval = ntohl (mp->retval);
4849   vam->result_ready = 1;
4850 }
4851
4852 static void
4853   vl_api_classify_table_by_interface_reply_t_handler_json
4854   (vl_api_classify_table_by_interface_reply_t * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   vat_json_node_t node;
4858
4859   vat_json_init_object (&node);
4860
4861   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4862   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4863   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4864
4865   vat_json_print (vam->ofp, &node);
4866   vat_json_free (&node);
4867
4868   vam->retval = ntohl (mp->retval);
4869   vam->result_ready = 1;
4870 }
4871
4872 static void vl_api_policer_add_del_reply_t_handler
4873   (vl_api_policer_add_del_reply_t * mp)
4874 {
4875   vat_main_t *vam = &vat_main;
4876   i32 retval = ntohl (mp->retval);
4877   if (vam->async_mode)
4878     {
4879       vam->async_errors += (retval < 0);
4880     }
4881   else
4882     {
4883       vam->retval = retval;
4884       vam->result_ready = 1;
4885       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4886         /*
4887          * Note: this is just barely thread-safe, depends on
4888          * the main thread spinning waiting for an answer...
4889          */
4890         errmsg ("policer index %d", ntohl (mp->policer_index));
4891     }
4892 }
4893
4894 static void vl_api_policer_add_del_reply_t_handler_json
4895   (vl_api_policer_add_del_reply_t * mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898   vat_json_node_t node;
4899
4900   vat_json_init_object (&node);
4901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4902   vat_json_object_add_uint (&node, "policer_index",
4903                             ntohl (mp->policer_index));
4904
4905   vat_json_print (vam->ofp, &node);
4906   vat_json_free (&node);
4907
4908   vam->retval = ntohl (mp->retval);
4909   vam->result_ready = 1;
4910 }
4911
4912 /* Format hex dump. */
4913 u8 *
4914 format_hex_bytes (u8 * s, va_list * va)
4915 {
4916   u8 *bytes = va_arg (*va, u8 *);
4917   int n_bytes = va_arg (*va, int);
4918   uword i;
4919
4920   /* Print short or long form depending on byte count. */
4921   uword short_form = n_bytes <= 32;
4922   u32 indent = format_get_indent (s);
4923
4924   if (n_bytes == 0)
4925     return s;
4926
4927   for (i = 0; i < n_bytes; i++)
4928     {
4929       if (!short_form && (i % 32) == 0)
4930         s = format (s, "%08x: ", i);
4931       s = format (s, "%02x", bytes[i]);
4932       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4933         s = format (s, "\n%U", format_white_space, indent);
4934     }
4935
4936   return s;
4937 }
4938
4939 static void
4940 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4941                                             * mp)
4942 {
4943   vat_main_t *vam = &vat_main;
4944   i32 retval = ntohl (mp->retval);
4945   if (retval == 0)
4946     {
4947       print (vam->ofp, "classify table info :");
4948       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4949              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4950              ntohl (mp->miss_next_index));
4951       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4952              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4953              ntohl (mp->match_n_vectors));
4954       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4955              ntohl (mp->mask_length));
4956     }
4957   vam->retval = retval;
4958   vam->result_ready = 1;
4959 }
4960
4961 static void
4962   vl_api_classify_table_info_reply_t_handler_json
4963   (vl_api_classify_table_info_reply_t * mp)
4964 {
4965   vat_main_t *vam = &vat_main;
4966   vat_json_node_t node;
4967
4968   i32 retval = ntohl (mp->retval);
4969   if (retval == 0)
4970     {
4971       vat_json_init_object (&node);
4972
4973       vat_json_object_add_int (&node, "sessions",
4974                                ntohl (mp->active_sessions));
4975       vat_json_object_add_int (&node, "nexttbl",
4976                                ntohl (mp->next_table_index));
4977       vat_json_object_add_int (&node, "nextnode",
4978                                ntohl (mp->miss_next_index));
4979       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4980       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4981       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4982       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4983                       ntohl (mp->mask_length), 0);
4984       vat_json_object_add_string_copy (&node, "mask", s);
4985
4986       vat_json_print (vam->ofp, &node);
4987       vat_json_free (&node);
4988     }
4989   vam->retval = ntohl (mp->retval);
4990   vam->result_ready = 1;
4991 }
4992
4993 static void
4994 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4995                                            mp)
4996 {
4997   vat_main_t *vam = &vat_main;
4998
4999   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5000          ntohl (mp->hit_next_index), ntohl (mp->advance),
5001          ntohl (mp->opaque_index));
5002   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5003          ntohl (mp->match_length));
5004 }
5005
5006 static void
5007   vl_api_classify_session_details_t_handler_json
5008   (vl_api_classify_session_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011   vat_json_node_t *node = NULL;
5012
5013   if (VAT_JSON_ARRAY != vam->json_tree.type)
5014     {
5015       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5016       vat_json_init_array (&vam->json_tree);
5017     }
5018   node = vat_json_array_add (&vam->json_tree);
5019
5020   vat_json_init_object (node);
5021   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5022   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5023   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5024   u8 *s =
5025     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5026             0);
5027   vat_json_object_add_string_copy (node, "match", s);
5028 }
5029
5030 static void vl_api_pg_create_interface_reply_t_handler
5031   (vl_api_pg_create_interface_reply_t * mp)
5032 {
5033   vat_main_t *vam = &vat_main;
5034
5035   vam->retval = ntohl (mp->retval);
5036   vam->result_ready = 1;
5037 }
5038
5039 static void vl_api_pg_create_interface_reply_t_handler_json
5040   (vl_api_pg_create_interface_reply_t * mp)
5041 {
5042   vat_main_t *vam = &vat_main;
5043   vat_json_node_t node;
5044
5045   i32 retval = ntohl (mp->retval);
5046   if (retval == 0)
5047     {
5048       vat_json_init_object (&node);
5049
5050       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5051
5052       vat_json_print (vam->ofp, &node);
5053       vat_json_free (&node);
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void vl_api_policer_classify_details_t_handler
5060   (vl_api_policer_classify_details_t * mp)
5061 {
5062   vat_main_t *vam = &vat_main;
5063
5064   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5065          ntohl (mp->table_index));
5066 }
5067
5068 static void vl_api_policer_classify_details_t_handler_json
5069   (vl_api_policer_classify_details_t * mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072   vat_json_node_t *node;
5073
5074   if (VAT_JSON_ARRAY != vam->json_tree.type)
5075     {
5076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5077       vat_json_init_array (&vam->json_tree);
5078     }
5079   node = vat_json_array_add (&vam->json_tree);
5080
5081   vat_json_init_object (node);
5082   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5083   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5084 }
5085
5086 static void vl_api_flow_classify_details_t_handler
5087   (vl_api_flow_classify_details_t * mp)
5088 {
5089   vat_main_t *vam = &vat_main;
5090
5091   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5092          ntohl (mp->table_index));
5093 }
5094
5095 static void vl_api_flow_classify_details_t_handler_json
5096   (vl_api_flow_classify_details_t * mp)
5097 {
5098   vat_main_t *vam = &vat_main;
5099   vat_json_node_t *node;
5100
5101   if (VAT_JSON_ARRAY != vam->json_tree.type)
5102     {
5103       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5104       vat_json_init_array (&vam->json_tree);
5105     }
5106   node = vat_json_array_add (&vam->json_tree);
5107
5108   vat_json_init_object (node);
5109   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5110   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5111 }
5112
5113 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5114 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5115 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5116 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5117 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5118 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5119 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5121 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5122 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5123
5124 /*
5125  * Generate boilerplate reply handlers, which
5126  * dig the return value out of the xxx_reply_t API message,
5127  * stick it into vam->retval, and set vam->result_ready
5128  *
5129  * Could also do this by pointing N message decode slots at
5130  * a single function, but that could break in subtle ways.
5131  */
5132
5133 #define foreach_standard_reply_retval_handler           \
5134 _(sw_interface_set_flags_reply)                         \
5135 _(sw_interface_add_del_address_reply)                   \
5136 _(sw_interface_set_rx_mode_reply)                       \
5137 _(sw_interface_set_rx_placement_reply)                  \
5138 _(sw_interface_set_table_reply)                         \
5139 _(sw_interface_set_mpls_enable_reply)                   \
5140 _(sw_interface_set_vpath_reply)                         \
5141 _(sw_interface_set_vxlan_bypass_reply)                  \
5142 _(sw_interface_set_geneve_bypass_reply)                 \
5143 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5144 _(sw_interface_set_l2_bridge_reply)                     \
5145 _(bridge_domain_add_del_reply)                          \
5146 _(sw_interface_set_l2_xconnect_reply)                   \
5147 _(l2fib_add_del_reply)                                  \
5148 _(l2fib_flush_int_reply)                                \
5149 _(l2fib_flush_bd_reply)                                 \
5150 _(ip_route_add_del_reply)                               \
5151 _(ip_table_add_del_reply)                               \
5152 _(ip_mroute_add_del_reply)                              \
5153 _(mpls_route_add_del_reply)                             \
5154 _(mpls_table_add_del_reply)                             \
5155 _(mpls_ip_bind_unbind_reply)                            \
5156 _(bier_route_add_del_reply)                             \
5157 _(bier_table_add_del_reply)                             \
5158 _(proxy_arp_add_del_reply)                              \
5159 _(proxy_arp_intfc_enable_disable_reply)                 \
5160 _(sw_interface_set_unnumbered_reply)                    \
5161 _(ip_neighbor_add_del_reply)                            \
5162 _(reset_fib_reply)                                      \
5163 _(dhcp_proxy_config_reply)                              \
5164 _(dhcp_proxy_set_vss_reply)                             \
5165 _(dhcp_client_config_reply)                             \
5166 _(set_ip_flow_hash_reply)                               \
5167 _(sw_interface_ip6_enable_disable_reply)                \
5168 _(ip6nd_proxy_add_del_reply)                            \
5169 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5170 _(sw_interface_ip6nd_ra_config_reply)                   \
5171 _(set_arp_neighbor_limit_reply)                         \
5172 _(l2_patch_add_del_reply)                               \
5173 _(sr_mpls_policy_add_reply)                             \
5174 _(sr_mpls_policy_mod_reply)                             \
5175 _(sr_mpls_policy_del_reply)                             \
5176 _(sr_policy_add_reply)                                  \
5177 _(sr_policy_mod_reply)                                  \
5178 _(sr_policy_del_reply)                                  \
5179 _(sr_localsid_add_del_reply)                            \
5180 _(sr_steering_add_del_reply)                            \
5181 _(classify_add_del_session_reply)                       \
5182 _(classify_set_interface_ip_table_reply)                \
5183 _(classify_set_interface_l2_tables_reply)               \
5184 _(l2tpv3_set_tunnel_cookies_reply)                      \
5185 _(l2tpv3_interface_enable_disable_reply)                \
5186 _(l2tpv3_set_lookup_key_reply)                          \
5187 _(l2_fib_clear_table_reply)                             \
5188 _(l2_interface_efp_filter_reply)                        \
5189 _(l2_interface_vlan_tag_rewrite_reply)                  \
5190 _(modify_vhost_user_if_reply)                           \
5191 _(delete_vhost_user_if_reply)                           \
5192 _(ip_probe_neighbor_reply)                              \
5193 _(ip_scan_neighbor_enable_disable_reply)                \
5194 _(want_ip4_arp_events_reply)                            \
5195 _(want_ip6_nd_events_reply)                             \
5196 _(want_l2_macs_events_reply)                            \
5197 _(input_acl_set_interface_reply)                        \
5198 _(ipsec_spd_add_del_reply)                              \
5199 _(ipsec_interface_add_del_spd_reply)                    \
5200 _(ipsec_spd_entry_add_del_reply)                        \
5201 _(ipsec_sad_entry_add_del_reply)                        \
5202 _(ipsec_tunnel_if_add_del_reply)                        \
5203 _(ipsec_tunnel_if_set_sa_reply)                         \
5204 _(delete_loopback_reply)                                \
5205 _(bd_ip_mac_add_del_reply)                              \
5206 _(bd_ip_mac_flush_reply)                                \
5207 _(want_interface_events_reply)                          \
5208 _(cop_interface_enable_disable_reply)                   \
5209 _(cop_whitelist_enable_disable_reply)                   \
5210 _(sw_interface_clear_stats_reply)                       \
5211 _(ioam_enable_reply)                                    \
5212 _(ioam_disable_reply)                                   \
5213 _(one_add_del_locator_reply)                            \
5214 _(one_add_del_local_eid_reply)                          \
5215 _(one_add_del_remote_mapping_reply)                     \
5216 _(one_add_del_adjacency_reply)                          \
5217 _(one_add_del_map_resolver_reply)                       \
5218 _(one_add_del_map_server_reply)                         \
5219 _(one_enable_disable_reply)                             \
5220 _(one_rloc_probe_enable_disable_reply)                  \
5221 _(one_map_register_enable_disable_reply)                \
5222 _(one_map_register_set_ttl_reply)                       \
5223 _(one_set_transport_protocol_reply)                     \
5224 _(one_map_register_fallback_threshold_reply)            \
5225 _(one_pitr_set_locator_set_reply)                       \
5226 _(one_map_request_mode_reply)                           \
5227 _(one_add_del_map_request_itr_rlocs_reply)              \
5228 _(one_eid_table_add_del_map_reply)                      \
5229 _(one_use_petr_reply)                                   \
5230 _(one_stats_enable_disable_reply)                       \
5231 _(one_add_del_l2_arp_entry_reply)                       \
5232 _(one_add_del_ndp_entry_reply)                          \
5233 _(one_stats_flush_reply)                                \
5234 _(one_enable_disable_xtr_mode_reply)                    \
5235 _(one_enable_disable_pitr_mode_reply)                   \
5236 _(one_enable_disable_petr_mode_reply)                   \
5237 _(gpe_enable_disable_reply)                             \
5238 _(gpe_set_encap_mode_reply)                             \
5239 _(gpe_add_del_iface_reply)                              \
5240 _(gpe_add_del_native_fwd_rpath_reply)                   \
5241 _(af_packet_delete_reply)                               \
5242 _(policer_classify_set_interface_reply)                 \
5243 _(netmap_create_reply)                                  \
5244 _(netmap_delete_reply)                                  \
5245 _(set_ipfix_exporter_reply)                             \
5246 _(set_ipfix_classify_stream_reply)                      \
5247 _(ipfix_classify_table_add_del_reply)                   \
5248 _(flow_classify_set_interface_reply)                    \
5249 _(sw_interface_span_enable_disable_reply)               \
5250 _(pg_capture_reply)                                     \
5251 _(pg_enable_disable_reply)                              \
5252 _(ip_source_and_port_range_check_add_del_reply)         \
5253 _(ip_source_and_port_range_check_interface_add_del_reply)\
5254 _(delete_subif_reply)                                   \
5255 _(l2_interface_pbb_tag_rewrite_reply)                   \
5256 _(set_punt_reply)                                       \
5257 _(feature_enable_disable_reply)                         \
5258 _(sw_interface_tag_add_del_reply)                       \
5259 _(hw_interface_set_mtu_reply)                           \
5260 _(p2p_ethernet_add_reply)                               \
5261 _(p2p_ethernet_del_reply)                               \
5262 _(lldp_config_reply)                                    \
5263 _(sw_interface_set_lldp_reply)                          \
5264 _(tcp_configure_src_addresses_reply)                    \
5265 _(dns_enable_disable_reply)                             \
5266 _(dns_name_server_add_del_reply)                        \
5267 _(session_rule_add_del_reply)                           \
5268 _(ip_container_proxy_add_del_reply)                     \
5269 _(output_acl_set_interface_reply)                       \
5270 _(qos_record_enable_disable_reply)
5271
5272 #define _(n)                                    \
5273     static void vl_api_##n##_t_handler          \
5274     (vl_api_##n##_t * mp)                       \
5275     {                                           \
5276         vat_main_t * vam = &vat_main;           \
5277         i32 retval = ntohl(mp->retval);         \
5278         if (vam->async_mode) {                  \
5279             vam->async_errors += (retval < 0);  \
5280         } else {                                \
5281             vam->retval = retval;               \
5282             vam->result_ready = 1;              \
5283         }                                       \
5284     }
5285 foreach_standard_reply_retval_handler;
5286 #undef _
5287
5288 #define _(n)                                    \
5289     static void vl_api_##n##_t_handler_json     \
5290     (vl_api_##n##_t * mp)                       \
5291     {                                           \
5292         vat_main_t * vam = &vat_main;           \
5293         vat_json_node_t node;                   \
5294         vat_json_init_object(&node);            \
5295         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5296         vat_json_print(vam->ofp, &node);        \
5297         vam->retval = ntohl(mp->retval);        \
5298         vam->result_ready = 1;                  \
5299     }
5300 foreach_standard_reply_retval_handler;
5301 #undef _
5302
5303 /*
5304  * Table of message reply handlers, must include boilerplate handlers
5305  * we just generated
5306  */
5307
5308 #define foreach_vpe_api_reply_msg                                       \
5309 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5310 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5311 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5312 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5313 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5314 _(CLI_REPLY, cli_reply)                                                 \
5315 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5316 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5317   sw_interface_add_del_address_reply)                                   \
5318 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5319 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5320 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5321 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5322 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5323 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5324 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5325 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5326 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5327 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5328   sw_interface_set_l2_xconnect_reply)                                   \
5329 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5330   sw_interface_set_l2_bridge_reply)                                     \
5331 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5332 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5333 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5334 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5335 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5336 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5337 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5338 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5339 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5340 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5341 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5342 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5343 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5344 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5345 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5346 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5347 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5348 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5349 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5350 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5351 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5352 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5353 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5354 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5355 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5356 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5357 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5358 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5359 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5360 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5361   proxy_arp_intfc_enable_disable_reply)                                 \
5362 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5363 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5364   sw_interface_set_unnumbered_reply)                                    \
5365 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5366 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5367 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5368 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5369 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5370 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5371 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5372 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5373 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5374 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5375   sw_interface_ip6_enable_disable_reply)                                \
5376 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5377 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5378 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5379   sw_interface_ip6nd_ra_prefix_reply)                                   \
5380 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5381   sw_interface_ip6nd_ra_config_reply)                                   \
5382 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5383 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5384 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5385 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5386 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5387 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5388 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5389 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5390 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5391 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5392 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5393 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5394 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5395 classify_set_interface_ip_table_reply)                                  \
5396 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5397   classify_set_interface_l2_tables_reply)                               \
5398 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5399 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5400 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5401 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5402 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5403   l2tpv3_interface_enable_disable_reply)                                \
5404 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5405 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5406 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5407 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5408 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5409 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5410 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5411 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5412 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5413 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5414 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5415 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5416 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5417 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5418 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5419 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5420 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5421 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5422 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5423 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5424 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5425 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5426 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5427 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5428 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5429 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5430 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5431 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5432 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5433 _(L2_MACS_EVENT, l2_macs_event)                                         \
5434 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5435 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5436 _(IP_DETAILS, ip_details)                                               \
5437 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5438 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5439 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5440 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5441 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5442 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5443 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5444 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5445 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5446 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5447 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5448 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5449 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5450 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5451 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5452 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5453 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5454 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5455 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5456 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5457 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5458 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5459 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5460 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5461 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5462 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5463 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5464 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5465 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5466   one_map_register_enable_disable_reply)                                \
5467 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5468 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5469 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5470 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5471   one_map_register_fallback_threshold_reply)                            \
5472 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5473   one_rloc_probe_enable_disable_reply)                                  \
5474 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5475 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5476 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5477 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5478 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5479 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5480 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5481 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5482 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5483 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5484 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5485 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5486 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5487 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5488 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5489 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5490   show_one_stats_enable_disable_reply)                                  \
5491 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5492 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5493 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5494 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5495 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5496 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5497 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5498 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5499   one_enable_disable_pitr_mode_reply)                                   \
5500 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5501   one_enable_disable_petr_mode_reply)                                   \
5502 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5503 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5504 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5505 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5506 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5507 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5508 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5509 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5510 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5511 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5512 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5513 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5514   gpe_add_del_native_fwd_rpath_reply)                                   \
5515 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5516   gpe_fwd_entry_path_details)                                           \
5517 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5518 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5519   one_add_del_map_request_itr_rlocs_reply)                              \
5520 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5521   one_get_map_request_itr_rlocs_reply)                                  \
5522 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5523 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5524 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5525 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5526 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5527 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5528   show_one_map_register_state_reply)                                    \
5529 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5530 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5531   show_one_map_register_fallback_threshold_reply)                       \
5532 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5533 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5534 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5535 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5536 _(POLICER_DETAILS, policer_details)                                     \
5537 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5538 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5539 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5540 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5541 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5542 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5543 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5544 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5545 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5546 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5547 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5548 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5549 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5550 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5551 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5552 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5553 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5554 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5555 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5556 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5557 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5558 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5559 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5560 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5561 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5562 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5563  ip_source_and_port_range_check_add_del_reply)                          \
5564 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5565  ip_source_and_port_range_check_interface_add_del_reply)                \
5566 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5567 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5568 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5569 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5570 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5571 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5572 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5573 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5574 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5575 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5576 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5577 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5578 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5579 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5580 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5581 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5582 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5583 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5584 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5585 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5586 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5587 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5588 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5589 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5590 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5591 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5592
5593 #define foreach_standalone_reply_msg                                    \
5594 _(SW_INTERFACE_EVENT, sw_interface_event)
5595
5596 typedef struct
5597 {
5598   u8 *name;
5599   u32 value;
5600 } name_sort_t;
5601
5602 #define STR_VTR_OP_CASE(op)     \
5603     case L2_VTR_ ## op:         \
5604         return "" # op;
5605
5606 static const char *
5607 str_vtr_op (u32 vtr_op)
5608 {
5609   switch (vtr_op)
5610     {
5611       STR_VTR_OP_CASE (DISABLED);
5612       STR_VTR_OP_CASE (PUSH_1);
5613       STR_VTR_OP_CASE (PUSH_2);
5614       STR_VTR_OP_CASE (POP_1);
5615       STR_VTR_OP_CASE (POP_2);
5616       STR_VTR_OP_CASE (TRANSLATE_1_1);
5617       STR_VTR_OP_CASE (TRANSLATE_1_2);
5618       STR_VTR_OP_CASE (TRANSLATE_2_1);
5619       STR_VTR_OP_CASE (TRANSLATE_2_2);
5620     }
5621
5622   return "UNKNOWN";
5623 }
5624
5625 static int
5626 dump_sub_interface_table (vat_main_t * vam)
5627 {
5628   const sw_interface_subif_t *sub = NULL;
5629
5630   if (vam->json_output)
5631     {
5632       clib_warning
5633         ("JSON output supported only for VPE API calls and dump_stats_table");
5634       return -99;
5635     }
5636
5637   print (vam->ofp,
5638          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5639          "Interface", "sw_if_index",
5640          "sub id", "dot1ad", "tags", "outer id",
5641          "inner id", "exact", "default", "outer any", "inner any");
5642
5643   vec_foreach (sub, vam->sw_if_subif_table)
5644   {
5645     print (vam->ofp,
5646            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5647            sub->interface_name,
5648            sub->sw_if_index,
5649            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5650            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5651            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5652            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5653     if (sub->vtr_op != L2_VTR_DISABLED)
5654       {
5655         print (vam->ofp,
5656                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5657                "tag1: %d tag2: %d ]",
5658                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5659                sub->vtr_tag1, sub->vtr_tag2);
5660       }
5661   }
5662
5663   return 0;
5664 }
5665
5666 static int
5667 name_sort_cmp (void *a1, void *a2)
5668 {
5669   name_sort_t *n1 = a1;
5670   name_sort_t *n2 = a2;
5671
5672   return strcmp ((char *) n1->name, (char *) n2->name);
5673 }
5674
5675 static int
5676 dump_interface_table (vat_main_t * vam)
5677 {
5678   hash_pair_t *p;
5679   name_sort_t *nses = 0, *ns;
5680
5681   if (vam->json_output)
5682     {
5683       clib_warning
5684         ("JSON output supported only for VPE API calls and dump_stats_table");
5685       return -99;
5686     }
5687
5688   /* *INDENT-OFF* */
5689   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5690   ({
5691     vec_add2 (nses, ns, 1);
5692     ns->name = (u8 *)(p->key);
5693     ns->value = (u32) p->value[0];
5694   }));
5695   /* *INDENT-ON* */
5696
5697   vec_sort_with_function (nses, name_sort_cmp);
5698
5699   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5700   vec_foreach (ns, nses)
5701   {
5702     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5703   }
5704   vec_free (nses);
5705   return 0;
5706 }
5707
5708 static int
5709 dump_ip_table (vat_main_t * vam, int is_ipv6)
5710 {
5711   const ip_details_t *det = NULL;
5712   const ip_address_details_t *address = NULL;
5713   u32 i = ~0;
5714
5715   print (vam->ofp, "%-12s", "sw_if_index");
5716
5717   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5718   {
5719     i++;
5720     if (!det->present)
5721       {
5722         continue;
5723       }
5724     print (vam->ofp, "%-12d", i);
5725     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5726     if (!det->addr)
5727       {
5728         continue;
5729       }
5730     vec_foreach (address, det->addr)
5731     {
5732       print (vam->ofp,
5733              "            %-30U%-13d",
5734              is_ipv6 ? format_ip6_address : format_ip4_address,
5735              address->ip, address->prefix_length);
5736     }
5737   }
5738
5739   return 0;
5740 }
5741
5742 static int
5743 dump_ipv4_table (vat_main_t * vam)
5744 {
5745   if (vam->json_output)
5746     {
5747       clib_warning
5748         ("JSON output supported only for VPE API calls and dump_stats_table");
5749       return -99;
5750     }
5751
5752   return dump_ip_table (vam, 0);
5753 }
5754
5755 static int
5756 dump_ipv6_table (vat_main_t * vam)
5757 {
5758   if (vam->json_output)
5759     {
5760       clib_warning
5761         ("JSON output supported only for VPE API calls and dump_stats_table");
5762       return -99;
5763     }
5764
5765   return dump_ip_table (vam, 1);
5766 }
5767
5768 /*
5769  * Pass CLI buffers directly in the CLI_INBAND API message,
5770  * instead of an additional shared memory area.
5771  */
5772 static int
5773 exec_inband (vat_main_t * vam)
5774 {
5775   vl_api_cli_inband_t *mp;
5776   unformat_input_t *i = vam->input;
5777   int ret;
5778
5779   if (vec_len (i->buffer) == 0)
5780     return -1;
5781
5782   if (vam->exec_mode == 0 && unformat (i, "mode"))
5783     {
5784       vam->exec_mode = 1;
5785       return 0;
5786     }
5787   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5788     {
5789       vam->exec_mode = 0;
5790       return 0;
5791     }
5792
5793   /*
5794    * In order for the CLI command to work, it
5795    * must be a vector ending in \n, not a C-string ending
5796    * in \n\0.
5797    */
5798   u32 len = vec_len (vam->input->buffer);
5799   M2 (CLI_INBAND, mp, len);
5800   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5801
5802   S (mp);
5803   W (ret);
5804   /* json responses may or may not include a useful reply... */
5805   if (vec_len (vam->cmd_reply))
5806     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5807   return ret;
5808 }
5809
5810 int
5811 exec (vat_main_t * vam)
5812 {
5813   return exec_inband (vam);
5814 }
5815
5816 static int
5817 api_create_loopback (vat_main_t * vam)
5818 {
5819   unformat_input_t *i = vam->input;
5820   vl_api_create_loopback_t *mp;
5821   vl_api_create_loopback_instance_t *mp_lbi;
5822   u8 mac_address[6];
5823   u8 mac_set = 0;
5824   u8 is_specified = 0;
5825   u32 user_instance = 0;
5826   int ret;
5827
5828   clib_memset (mac_address, 0, sizeof (mac_address));
5829
5830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831     {
5832       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5833         mac_set = 1;
5834       if (unformat (i, "instance %d", &user_instance))
5835         is_specified = 1;
5836       else
5837         break;
5838     }
5839
5840   if (is_specified)
5841     {
5842       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5843       mp_lbi->is_specified = is_specified;
5844       if (is_specified)
5845         mp_lbi->user_instance = htonl (user_instance);
5846       if (mac_set)
5847         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5848       S (mp_lbi);
5849     }
5850   else
5851     {
5852       /* Construct the API message */
5853       M (CREATE_LOOPBACK, mp);
5854       if (mac_set)
5855         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5856       S (mp);
5857     }
5858
5859   W (ret);
5860   return ret;
5861 }
5862
5863 static int
5864 api_delete_loopback (vat_main_t * vam)
5865 {
5866   unformat_input_t *i = vam->input;
5867   vl_api_delete_loopback_t *mp;
5868   u32 sw_if_index = ~0;
5869   int ret;
5870
5871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872     {
5873       if (unformat (i, "sw_if_index %d", &sw_if_index))
5874         ;
5875       else
5876         break;
5877     }
5878
5879   if (sw_if_index == ~0)
5880     {
5881       errmsg ("missing sw_if_index");
5882       return -99;
5883     }
5884
5885   /* Construct the API message */
5886   M (DELETE_LOOPBACK, mp);
5887   mp->sw_if_index = ntohl (sw_if_index);
5888
5889   S (mp);
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_want_interface_events (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_want_interface_events_t *mp;
5899   int enable = -1;
5900   int ret;
5901
5902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5903     {
5904       if (unformat (i, "enable"))
5905         enable = 1;
5906       else if (unformat (i, "disable"))
5907         enable = 0;
5908       else
5909         break;
5910     }
5911
5912   if (enable == -1)
5913     {
5914       errmsg ("missing enable|disable");
5915       return -99;
5916     }
5917
5918   M (WANT_INTERFACE_EVENTS, mp);
5919   mp->enable_disable = enable;
5920
5921   vam->interface_event_display = enable;
5922
5923   S (mp);
5924   W (ret);
5925   return ret;
5926 }
5927
5928
5929 /* Note: non-static, called once to set up the initial intfc table */
5930 int
5931 api_sw_interface_dump (vat_main_t * vam)
5932 {
5933   vl_api_sw_interface_dump_t *mp;
5934   vl_api_control_ping_t *mp_ping;
5935   hash_pair_t *p;
5936   name_sort_t *nses = 0, *ns;
5937   sw_interface_subif_t *sub = NULL;
5938   int ret;
5939
5940   /* Toss the old name table */
5941   /* *INDENT-OFF* */
5942   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5943   ({
5944     vec_add2 (nses, ns, 1);
5945     ns->name = (u8 *)(p->key);
5946     ns->value = (u32) p->value[0];
5947   }));
5948   /* *INDENT-ON* */
5949
5950   hash_free (vam->sw_if_index_by_interface_name);
5951
5952   vec_foreach (ns, nses) vec_free (ns->name);
5953
5954   vec_free (nses);
5955
5956   vec_foreach (sub, vam->sw_if_subif_table)
5957   {
5958     vec_free (sub->interface_name);
5959   }
5960   vec_free (vam->sw_if_subif_table);
5961
5962   /* recreate the interface name hash table */
5963   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5964
5965   /*
5966    * Ask for all interface names. Otherwise, the epic catalog of
5967    * name filters becomes ridiculously long, and vat ends up needing
5968    * to be taught about new interface types.
5969    */
5970   M (SW_INTERFACE_DUMP, mp);
5971   S (mp);
5972
5973   /* Use a control ping for synchronization */
5974   MPING (CONTROL_PING, mp_ping);
5975   S (mp_ping);
5976
5977   W (ret);
5978   return ret;
5979 }
5980
5981 static int
5982 api_sw_interface_set_flags (vat_main_t * vam)
5983 {
5984   unformat_input_t *i = vam->input;
5985   vl_api_sw_interface_set_flags_t *mp;
5986   u32 sw_if_index;
5987   u8 sw_if_index_set = 0;
5988   u8 admin_up = 0;
5989   int ret;
5990
5991   /* Parse args required to build the message */
5992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5993     {
5994       if (unformat (i, "admin-up"))
5995         admin_up = 1;
5996       else if (unformat (i, "admin-down"))
5997         admin_up = 0;
5998       else
5999         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6000         sw_if_index_set = 1;
6001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6002         sw_if_index_set = 1;
6003       else
6004         break;
6005     }
6006
6007   if (sw_if_index_set == 0)
6008     {
6009       errmsg ("missing interface name or sw_if_index");
6010       return -99;
6011     }
6012
6013   /* Construct the API message */
6014   M (SW_INTERFACE_SET_FLAGS, mp);
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->admin_up_down = admin_up;
6017
6018   /* send it... */
6019   S (mp);
6020
6021   /* Wait for a reply, return the good/bad news... */
6022   W (ret);
6023   return ret;
6024 }
6025
6026 static int
6027 api_sw_interface_set_rx_mode (vat_main_t * vam)
6028 {
6029   unformat_input_t *i = vam->input;
6030   vl_api_sw_interface_set_rx_mode_t *mp;
6031   u32 sw_if_index;
6032   u8 sw_if_index_set = 0;
6033   int ret;
6034   u8 queue_id_valid = 0;
6035   u32 queue_id;
6036   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6037
6038   /* Parse args required to build the message */
6039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6040     {
6041       if (unformat (i, "queue %d", &queue_id))
6042         queue_id_valid = 1;
6043       else if (unformat (i, "polling"))
6044         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6045       else if (unformat (i, "interrupt"))
6046         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6047       else if (unformat (i, "adaptive"))
6048         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6049       else
6050         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6051         sw_if_index_set = 1;
6052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6053         sw_if_index_set = 1;
6054       else
6055         break;
6056     }
6057
6058   if (sw_if_index_set == 0)
6059     {
6060       errmsg ("missing interface name or sw_if_index");
6061       return -99;
6062     }
6063   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6064     {
6065       errmsg ("missing rx-mode");
6066       return -99;
6067     }
6068
6069   /* Construct the API message */
6070   M (SW_INTERFACE_SET_RX_MODE, mp);
6071   mp->sw_if_index = ntohl (sw_if_index);
6072   mp->mode = mode;
6073   mp->queue_id_valid = queue_id_valid;
6074   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6075
6076   /* send it... */
6077   S (mp);
6078
6079   /* Wait for a reply, return the good/bad news... */
6080   W (ret);
6081   return ret;
6082 }
6083
6084 static int
6085 api_sw_interface_set_rx_placement (vat_main_t * vam)
6086 {
6087   unformat_input_t *i = vam->input;
6088   vl_api_sw_interface_set_rx_placement_t *mp;
6089   u32 sw_if_index;
6090   u8 sw_if_index_set = 0;
6091   int ret;
6092   u8 is_main = 0;
6093   u32 queue_id, thread_index;
6094
6095   /* Parse args required to build the message */
6096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6097     {
6098       if (unformat (i, "queue %d", &queue_id))
6099         ;
6100       else if (unformat (i, "main"))
6101         is_main = 1;
6102       else if (unformat (i, "worker %d", &thread_index))
6103         ;
6104       else
6105         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6106         sw_if_index_set = 1;
6107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6108         sw_if_index_set = 1;
6109       else
6110         break;
6111     }
6112
6113   if (sw_if_index_set == 0)
6114     {
6115       errmsg ("missing interface name or sw_if_index");
6116       return -99;
6117     }
6118
6119   if (is_main)
6120     thread_index = 0;
6121   /* Construct the API message */
6122   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6123   mp->sw_if_index = ntohl (sw_if_index);
6124   mp->worker_id = ntohl (thread_index);
6125   mp->queue_id = ntohl (queue_id);
6126   mp->is_main = is_main;
6127
6128   /* send it... */
6129   S (mp);
6130   /* Wait for a reply, return the good/bad news... */
6131   W (ret);
6132   return ret;
6133 }
6134
6135 static void vl_api_sw_interface_rx_placement_details_t_handler
6136   (vl_api_sw_interface_rx_placement_details_t * mp)
6137 {
6138   vat_main_t *vam = &vat_main;
6139   u32 worker_id = ntohl (mp->worker_id);
6140
6141   print (vam->ofp,
6142          "\n%-11d %-11s %-6d %-5d %-9s",
6143          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6144          worker_id, ntohl (mp->queue_id),
6145          (mp->mode ==
6146           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6147 }
6148
6149 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6150   (vl_api_sw_interface_rx_placement_details_t * mp)
6151 {
6152   vat_main_t *vam = &vat_main;
6153   vat_json_node_t *node = NULL;
6154
6155   if (VAT_JSON_ARRAY != vam->json_tree.type)
6156     {
6157       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6158       vat_json_init_array (&vam->json_tree);
6159     }
6160   node = vat_json_array_add (&vam->json_tree);
6161
6162   vat_json_init_object (node);
6163   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6164   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6165   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6166   vat_json_object_add_uint (node, "mode", mp->mode);
6167 }
6168
6169 static int
6170 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6171 {
6172   unformat_input_t *i = vam->input;
6173   vl_api_sw_interface_rx_placement_dump_t *mp;
6174   vl_api_control_ping_t *mp_ping;
6175   int ret;
6176   u32 sw_if_index;
6177   u8 sw_if_index_set = 0;
6178
6179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6180     {
6181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6182         sw_if_index_set++;
6183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6184         sw_if_index_set++;
6185       else
6186         break;
6187     }
6188
6189   print (vam->ofp,
6190          "\n%-11s %-11s %-6s %-5s %-4s",
6191          "sw_if_index", "main/worker", "thread", "queue", "mode");
6192
6193   /* Dump Interface rx placement */
6194   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6195
6196   if (sw_if_index_set)
6197     mp->sw_if_index = htonl (sw_if_index);
6198   else
6199     mp->sw_if_index = ~0;
6200
6201   S (mp);
6202
6203   /* Use a control ping for synchronization */
6204   MPING (CONTROL_PING, mp_ping);
6205   S (mp_ping);
6206
6207   W (ret);
6208   return ret;
6209 }
6210
6211 static int
6212 api_sw_interface_clear_stats (vat_main_t * vam)
6213 {
6214   unformat_input_t *i = vam->input;
6215   vl_api_sw_interface_clear_stats_t *mp;
6216   u32 sw_if_index;
6217   u8 sw_if_index_set = 0;
6218   int ret;
6219
6220   /* Parse args required to build the message */
6221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6222     {
6223       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6224         sw_if_index_set = 1;
6225       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6226         sw_if_index_set = 1;
6227       else
6228         break;
6229     }
6230
6231   /* Construct the API message */
6232   M (SW_INTERFACE_CLEAR_STATS, mp);
6233
6234   if (sw_if_index_set == 1)
6235     mp->sw_if_index = ntohl (sw_if_index);
6236   else
6237     mp->sw_if_index = ~0;
6238
6239   /* send it... */
6240   S (mp);
6241
6242   /* Wait for a reply, return the good/bad news... */
6243   W (ret);
6244   return ret;
6245 }
6246
6247 static int
6248 api_sw_interface_add_del_address (vat_main_t * vam)
6249 {
6250   unformat_input_t *i = vam->input;
6251   vl_api_sw_interface_add_del_address_t *mp;
6252   u32 sw_if_index;
6253   u8 sw_if_index_set = 0;
6254   u8 is_add = 1, del_all = 0;
6255   u32 address_length = 0;
6256   u8 v4_address_set = 0;
6257   u8 v6_address_set = 0;
6258   ip4_address_t v4address;
6259   ip6_address_t v6address;
6260   int ret;
6261
6262   /* Parse args required to build the message */
6263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6264     {
6265       if (unformat (i, "del-all"))
6266         del_all = 1;
6267       else if (unformat (i, "del"))
6268         is_add = 0;
6269       else
6270         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6271         sw_if_index_set = 1;
6272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6273         sw_if_index_set = 1;
6274       else if (unformat (i, "%U/%d",
6275                          unformat_ip4_address, &v4address, &address_length))
6276         v4_address_set = 1;
6277       else if (unformat (i, "%U/%d",
6278                          unformat_ip6_address, &v6address, &address_length))
6279         v6_address_set = 1;
6280       else
6281         break;
6282     }
6283
6284   if (sw_if_index_set == 0)
6285     {
6286       errmsg ("missing interface name or sw_if_index");
6287       return -99;
6288     }
6289   if (v4_address_set && v6_address_set)
6290     {
6291       errmsg ("both v4 and v6 addresses set");
6292       return -99;
6293     }
6294   if (!v4_address_set && !v6_address_set && !del_all)
6295     {
6296       errmsg ("no addresses set");
6297       return -99;
6298     }
6299
6300   /* Construct the API message */
6301   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6302
6303   mp->sw_if_index = ntohl (sw_if_index);
6304   mp->is_add = is_add;
6305   mp->del_all = del_all;
6306   if (v6_address_set)
6307     {
6308       mp->is_ipv6 = 1;
6309       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6310     }
6311   else
6312     {
6313       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6314     }
6315   mp->address_length = address_length;
6316
6317   /* send it... */
6318   S (mp);
6319
6320   /* Wait for a reply, return good/bad news  */
6321   W (ret);
6322   return ret;
6323 }
6324
6325 static int
6326 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6327 {
6328   unformat_input_t *i = vam->input;
6329   vl_api_sw_interface_set_mpls_enable_t *mp;
6330   u32 sw_if_index;
6331   u8 sw_if_index_set = 0;
6332   u8 enable = 1;
6333   int ret;
6334
6335   /* Parse args required to build the message */
6336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6337     {
6338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6339         sw_if_index_set = 1;
6340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6341         sw_if_index_set = 1;
6342       else if (unformat (i, "disable"))
6343         enable = 0;
6344       else if (unformat (i, "dis"))
6345         enable = 0;
6346       else
6347         break;
6348     }
6349
6350   if (sw_if_index_set == 0)
6351     {
6352       errmsg ("missing interface name or sw_if_index");
6353       return -99;
6354     }
6355
6356   /* Construct the API message */
6357   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6358
6359   mp->sw_if_index = ntohl (sw_if_index);
6360   mp->enable = enable;
6361
6362   /* send it... */
6363   S (mp);
6364
6365   /* Wait for a reply... */
6366   W (ret);
6367   return ret;
6368 }
6369
6370 static int
6371 api_sw_interface_set_table (vat_main_t * vam)
6372 {
6373   unformat_input_t *i = vam->input;
6374   vl_api_sw_interface_set_table_t *mp;
6375   u32 sw_if_index, vrf_id = 0;
6376   u8 sw_if_index_set = 0;
6377   u8 is_ipv6 = 0;
6378   int ret;
6379
6380   /* Parse args required to build the message */
6381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6382     {
6383       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6384         sw_if_index_set = 1;
6385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6386         sw_if_index_set = 1;
6387       else if (unformat (i, "vrf %d", &vrf_id))
6388         ;
6389       else if (unformat (i, "ipv6"))
6390         is_ipv6 = 1;
6391       else
6392         break;
6393     }
6394
6395   if (sw_if_index_set == 0)
6396     {
6397       errmsg ("missing interface name or sw_if_index");
6398       return -99;
6399     }
6400
6401   /* Construct the API message */
6402   M (SW_INTERFACE_SET_TABLE, mp);
6403
6404   mp->sw_if_index = ntohl (sw_if_index);
6405   mp->is_ipv6 = is_ipv6;
6406   mp->vrf_id = ntohl (vrf_id);
6407
6408   /* send it... */
6409   S (mp);
6410
6411   /* Wait for a reply... */
6412   W (ret);
6413   return ret;
6414 }
6415
6416 static void vl_api_sw_interface_get_table_reply_t_handler
6417   (vl_api_sw_interface_get_table_reply_t * mp)
6418 {
6419   vat_main_t *vam = &vat_main;
6420
6421   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6422
6423   vam->retval = ntohl (mp->retval);
6424   vam->result_ready = 1;
6425
6426 }
6427
6428 static void vl_api_sw_interface_get_table_reply_t_handler_json
6429   (vl_api_sw_interface_get_table_reply_t * mp)
6430 {
6431   vat_main_t *vam = &vat_main;
6432   vat_json_node_t node;
6433
6434   vat_json_init_object (&node);
6435   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6436   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6437
6438   vat_json_print (vam->ofp, &node);
6439   vat_json_free (&node);
6440
6441   vam->retval = ntohl (mp->retval);
6442   vam->result_ready = 1;
6443 }
6444
6445 static int
6446 api_sw_interface_get_table (vat_main_t * vam)
6447 {
6448   unformat_input_t *i = vam->input;
6449   vl_api_sw_interface_get_table_t *mp;
6450   u32 sw_if_index;
6451   u8 sw_if_index_set = 0;
6452   u8 is_ipv6 = 0;
6453   int ret;
6454
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "ipv6"))
6462         is_ipv6 = 1;
6463       else
6464         break;
6465     }
6466
6467   if (sw_if_index_set == 0)
6468     {
6469       errmsg ("missing interface name or sw_if_index");
6470       return -99;
6471     }
6472
6473   M (SW_INTERFACE_GET_TABLE, mp);
6474   mp->sw_if_index = htonl (sw_if_index);
6475   mp->is_ipv6 = is_ipv6;
6476
6477   S (mp);
6478   W (ret);
6479   return ret;
6480 }
6481
6482 static int
6483 api_sw_interface_set_vpath (vat_main_t * vam)
6484 {
6485   unformat_input_t *i = vam->input;
6486   vl_api_sw_interface_set_vpath_t *mp;
6487   u32 sw_if_index = 0;
6488   u8 sw_if_index_set = 0;
6489   u8 is_enable = 0;
6490   int ret;
6491
6492   /* Parse args required to build the message */
6493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6494     {
6495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6496         sw_if_index_set = 1;
6497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6498         sw_if_index_set = 1;
6499       else if (unformat (i, "enable"))
6500         is_enable = 1;
6501       else if (unformat (i, "disable"))
6502         is_enable = 0;
6503       else
6504         break;
6505     }
6506
6507   if (sw_if_index_set == 0)
6508     {
6509       errmsg ("missing interface name or sw_if_index");
6510       return -99;
6511     }
6512
6513   /* Construct the API message */
6514   M (SW_INTERFACE_SET_VPATH, mp);
6515
6516   mp->sw_if_index = ntohl (sw_if_index);
6517   mp->enable = is_enable;
6518
6519   /* send it... */
6520   S (mp);
6521
6522   /* Wait for a reply... */
6523   W (ret);
6524   return ret;
6525 }
6526
6527 static int
6528 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6529 {
6530   unformat_input_t *i = vam->input;
6531   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6532   u32 sw_if_index = 0;
6533   u8 sw_if_index_set = 0;
6534   u8 is_enable = 1;
6535   u8 is_ipv6 = 0;
6536   int ret;
6537
6538   /* Parse args required to build the message */
6539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6540     {
6541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6542         sw_if_index_set = 1;
6543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6544         sw_if_index_set = 1;
6545       else if (unformat (i, "enable"))
6546         is_enable = 1;
6547       else if (unformat (i, "disable"))
6548         is_enable = 0;
6549       else if (unformat (i, "ip4"))
6550         is_ipv6 = 0;
6551       else if (unformat (i, "ip6"))
6552         is_ipv6 = 1;
6553       else
6554         break;
6555     }
6556
6557   if (sw_if_index_set == 0)
6558     {
6559       errmsg ("missing interface name or sw_if_index");
6560       return -99;
6561     }
6562
6563   /* Construct the API message */
6564   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6565
6566   mp->sw_if_index = ntohl (sw_if_index);
6567   mp->enable = is_enable;
6568   mp->is_ipv6 = is_ipv6;
6569
6570   /* send it... */
6571   S (mp);
6572
6573   /* Wait for a reply... */
6574   W (ret);
6575   return ret;
6576 }
6577
6578 static int
6579 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6580 {
6581   unformat_input_t *i = vam->input;
6582   vl_api_sw_interface_set_geneve_bypass_t *mp;
6583   u32 sw_if_index = 0;
6584   u8 sw_if_index_set = 0;
6585   u8 is_enable = 1;
6586   u8 is_ipv6 = 0;
6587   int ret;
6588
6589   /* Parse args required to build the message */
6590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6591     {
6592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6593         sw_if_index_set = 1;
6594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6595         sw_if_index_set = 1;
6596       else if (unformat (i, "enable"))
6597         is_enable = 1;
6598       else if (unformat (i, "disable"))
6599         is_enable = 0;
6600       else if (unformat (i, "ip4"))
6601         is_ipv6 = 0;
6602       else if (unformat (i, "ip6"))
6603         is_ipv6 = 1;
6604       else
6605         break;
6606     }
6607
6608   if (sw_if_index_set == 0)
6609     {
6610       errmsg ("missing interface name or sw_if_index");
6611       return -99;
6612     }
6613
6614   /* Construct the API message */
6615   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6616
6617   mp->sw_if_index = ntohl (sw_if_index);
6618   mp->enable = is_enable;
6619   mp->is_ipv6 = is_ipv6;
6620
6621   /* send it... */
6622   S (mp);
6623
6624   /* Wait for a reply... */
6625   W (ret);
6626   return ret;
6627 }
6628
6629 static int
6630 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6631 {
6632   unformat_input_t *i = vam->input;
6633   vl_api_sw_interface_set_l2_xconnect_t *mp;
6634   u32 rx_sw_if_index;
6635   u8 rx_sw_if_index_set = 0;
6636   u32 tx_sw_if_index;
6637   u8 tx_sw_if_index_set = 0;
6638   u8 enable = 1;
6639   int ret;
6640
6641   /* Parse args required to build the message */
6642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6643     {
6644       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6645         rx_sw_if_index_set = 1;
6646       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6647         tx_sw_if_index_set = 1;
6648       else if (unformat (i, "rx"))
6649         {
6650           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651             {
6652               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6653                             &rx_sw_if_index))
6654                 rx_sw_if_index_set = 1;
6655             }
6656           else
6657             break;
6658         }
6659       else if (unformat (i, "tx"))
6660         {
6661           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6662             {
6663               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6664                             &tx_sw_if_index))
6665                 tx_sw_if_index_set = 1;
6666             }
6667           else
6668             break;
6669         }
6670       else if (unformat (i, "enable"))
6671         enable = 1;
6672       else if (unformat (i, "disable"))
6673         enable = 0;
6674       else
6675         break;
6676     }
6677
6678   if (rx_sw_if_index_set == 0)
6679     {
6680       errmsg ("missing rx interface name or rx_sw_if_index");
6681       return -99;
6682     }
6683
6684   if (enable && (tx_sw_if_index_set == 0))
6685     {
6686       errmsg ("missing tx interface name or tx_sw_if_index");
6687       return -99;
6688     }
6689
6690   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6691
6692   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6693   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6694   mp->enable = enable;
6695
6696   S (mp);
6697   W (ret);
6698   return ret;
6699 }
6700
6701 static int
6702 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_set_l2_bridge_t *mp;
6706   vl_api_l2_port_type_t port_type;
6707   u32 rx_sw_if_index;
6708   u8 rx_sw_if_index_set = 0;
6709   u32 bd_id;
6710   u8 bd_id_set = 0;
6711   u32 shg = 0;
6712   u8 enable = 1;
6713   int ret;
6714
6715   port_type = L2_API_PORT_TYPE_NORMAL;
6716
6717   /* Parse args required to build the message */
6718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6719     {
6720       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6721         rx_sw_if_index_set = 1;
6722       else if (unformat (i, "bd_id %d", &bd_id))
6723         bd_id_set = 1;
6724       else
6725         if (unformat
6726             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6727         rx_sw_if_index_set = 1;
6728       else if (unformat (i, "shg %d", &shg))
6729         ;
6730       else if (unformat (i, "bvi"))
6731         port_type = L2_API_PORT_TYPE_BVI;
6732       else if (unformat (i, "uu-fwd"))
6733         port_type = L2_API_PORT_TYPE_UU_FWD;
6734       else if (unformat (i, "enable"))
6735         enable = 1;
6736       else if (unformat (i, "disable"))
6737         enable = 0;
6738       else
6739         break;
6740     }
6741
6742   if (rx_sw_if_index_set == 0)
6743     {
6744       errmsg ("missing rx interface name or sw_if_index");
6745       return -99;
6746     }
6747
6748   if (enable && (bd_id_set == 0))
6749     {
6750       errmsg ("missing bridge domain");
6751       return -99;
6752     }
6753
6754   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6755
6756   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6757   mp->bd_id = ntohl (bd_id);
6758   mp->shg = (u8) shg;
6759   mp->port_type = ntohl (port_type);
6760   mp->enable = enable;
6761
6762   S (mp);
6763   W (ret);
6764   return ret;
6765 }
6766
6767 static int
6768 api_bridge_domain_dump (vat_main_t * vam)
6769 {
6770   unformat_input_t *i = vam->input;
6771   vl_api_bridge_domain_dump_t *mp;
6772   vl_api_control_ping_t *mp_ping;
6773   u32 bd_id = ~0;
6774   int ret;
6775
6776   /* Parse args required to build the message */
6777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6778     {
6779       if (unformat (i, "bd_id %d", &bd_id))
6780         ;
6781       else
6782         break;
6783     }
6784
6785   M (BRIDGE_DOMAIN_DUMP, mp);
6786   mp->bd_id = ntohl (bd_id);
6787   S (mp);
6788
6789   /* Use a control ping for synchronization */
6790   MPING (CONTROL_PING, mp_ping);
6791   S (mp_ping);
6792
6793   W (ret);
6794   return ret;
6795 }
6796
6797 static int
6798 api_bridge_domain_add_del (vat_main_t * vam)
6799 {
6800   unformat_input_t *i = vam->input;
6801   vl_api_bridge_domain_add_del_t *mp;
6802   u32 bd_id = ~0;
6803   u8 is_add = 1;
6804   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6805   u8 *bd_tag = NULL;
6806   u32 mac_age = 0;
6807   int ret;
6808
6809   /* Parse args required to build the message */
6810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6811     {
6812       if (unformat (i, "bd_id %d", &bd_id))
6813         ;
6814       else if (unformat (i, "flood %d", &flood))
6815         ;
6816       else if (unformat (i, "uu-flood %d", &uu_flood))
6817         ;
6818       else if (unformat (i, "forward %d", &forward))
6819         ;
6820       else if (unformat (i, "learn %d", &learn))
6821         ;
6822       else if (unformat (i, "arp-term %d", &arp_term))
6823         ;
6824       else if (unformat (i, "mac-age %d", &mac_age))
6825         ;
6826       else if (unformat (i, "bd-tag %s", &bd_tag))
6827         ;
6828       else if (unformat (i, "del"))
6829         {
6830           is_add = 0;
6831           flood = uu_flood = forward = learn = 0;
6832         }
6833       else
6834         break;
6835     }
6836
6837   if (bd_id == ~0)
6838     {
6839       errmsg ("missing bridge domain");
6840       ret = -99;
6841       goto done;
6842     }
6843
6844   if (mac_age > 255)
6845     {
6846       errmsg ("mac age must be less than 256 ");
6847       ret = -99;
6848       goto done;
6849     }
6850
6851   if ((bd_tag) && (vec_len (bd_tag) > 63))
6852     {
6853       errmsg ("bd-tag cannot be longer than 63");
6854       ret = -99;
6855       goto done;
6856     }
6857
6858   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6859
6860   mp->bd_id = ntohl (bd_id);
6861   mp->flood = flood;
6862   mp->uu_flood = uu_flood;
6863   mp->forward = forward;
6864   mp->learn = learn;
6865   mp->arp_term = arp_term;
6866   mp->is_add = is_add;
6867   mp->mac_age = (u8) mac_age;
6868   if (bd_tag)
6869     {
6870       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6871       mp->bd_tag[vec_len (bd_tag)] = 0;
6872     }
6873   S (mp);
6874   W (ret);
6875
6876 done:
6877   vec_free (bd_tag);
6878   return ret;
6879 }
6880
6881 static int
6882 api_l2fib_flush_bd (vat_main_t * vam)
6883 {
6884   unformat_input_t *i = vam->input;
6885   vl_api_l2fib_flush_bd_t *mp;
6886   u32 bd_id = ~0;
6887   int ret;
6888
6889   /* Parse args required to build the message */
6890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891     {
6892       if (unformat (i, "bd_id %d", &bd_id));
6893       else
6894         break;
6895     }
6896
6897   if (bd_id == ~0)
6898     {
6899       errmsg ("missing bridge domain");
6900       return -99;
6901     }
6902
6903   M (L2FIB_FLUSH_BD, mp);
6904
6905   mp->bd_id = htonl (bd_id);
6906
6907   S (mp);
6908   W (ret);
6909   return ret;
6910 }
6911
6912 static int
6913 api_l2fib_flush_int (vat_main_t * vam)
6914 {
6915   unformat_input_t *i = vam->input;
6916   vl_api_l2fib_flush_int_t *mp;
6917   u32 sw_if_index = ~0;
6918   int ret;
6919
6920   /* Parse args required to build the message */
6921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6922     {
6923       if (unformat (i, "sw_if_index %d", &sw_if_index));
6924       else
6925         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6926       else
6927         break;
6928     }
6929
6930   if (sw_if_index == ~0)
6931     {
6932       errmsg ("missing interface name or sw_if_index");
6933       return -99;
6934     }
6935
6936   M (L2FIB_FLUSH_INT, mp);
6937
6938   mp->sw_if_index = ntohl (sw_if_index);
6939
6940   S (mp);
6941   W (ret);
6942   return ret;
6943 }
6944
6945 static int
6946 api_l2fib_add_del (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_l2fib_add_del_t *mp;
6950   f64 timeout;
6951   u8 mac[6] = { 0 };
6952   u8 mac_set = 0;
6953   u32 bd_id;
6954   u8 bd_id_set = 0;
6955   u32 sw_if_index = 0;
6956   u8 sw_if_index_set = 0;
6957   u8 is_add = 1;
6958   u8 static_mac = 0;
6959   u8 filter_mac = 0;
6960   u8 bvi_mac = 0;
6961   int count = 1;
6962   f64 before = 0;
6963   int j;
6964
6965   /* Parse args required to build the message */
6966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6967     {
6968       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6969         mac_set = 1;
6970       else if (unformat (i, "bd_id %d", &bd_id))
6971         bd_id_set = 1;
6972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6973         sw_if_index_set = 1;
6974       else if (unformat (i, "sw_if"))
6975         {
6976           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6977             {
6978               if (unformat
6979                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6980                 sw_if_index_set = 1;
6981             }
6982           else
6983             break;
6984         }
6985       else if (unformat (i, "static"))
6986         static_mac = 1;
6987       else if (unformat (i, "filter"))
6988         {
6989           filter_mac = 1;
6990           static_mac = 1;
6991         }
6992       else if (unformat (i, "bvi"))
6993         {
6994           bvi_mac = 1;
6995           static_mac = 1;
6996         }
6997       else if (unformat (i, "del"))
6998         is_add = 0;
6999       else if (unformat (i, "count %d", &count))
7000         ;
7001       else
7002         break;
7003     }
7004
7005   if (mac_set == 0)
7006     {
7007       errmsg ("missing mac address");
7008       return -99;
7009     }
7010
7011   if (bd_id_set == 0)
7012     {
7013       errmsg ("missing bridge domain");
7014       return -99;
7015     }
7016
7017   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7018     {
7019       errmsg ("missing interface name or sw_if_index");
7020       return -99;
7021     }
7022
7023   if (count > 1)
7024     {
7025       /* Turn on async mode */
7026       vam->async_mode = 1;
7027       vam->async_errors = 0;
7028       before = vat_time_now (vam);
7029     }
7030
7031   for (j = 0; j < count; j++)
7032     {
7033       M (L2FIB_ADD_DEL, mp);
7034
7035       clib_memcpy (mp->mac, mac, 6);
7036       mp->bd_id = ntohl (bd_id);
7037       mp->is_add = is_add;
7038       mp->sw_if_index = ntohl (sw_if_index);
7039
7040       if (is_add)
7041         {
7042           mp->static_mac = static_mac;
7043           mp->filter_mac = filter_mac;
7044           mp->bvi_mac = bvi_mac;
7045         }
7046       increment_mac_address (mac);
7047       /* send it... */
7048       S (mp);
7049     }
7050
7051   if (count > 1)
7052     {
7053       vl_api_control_ping_t *mp_ping;
7054       f64 after;
7055
7056       /* Shut off async mode */
7057       vam->async_mode = 0;
7058
7059       MPING (CONTROL_PING, mp_ping);
7060       S (mp_ping);
7061
7062       timeout = vat_time_now (vam) + 1.0;
7063       while (vat_time_now (vam) < timeout)
7064         if (vam->result_ready == 1)
7065           goto out;
7066       vam->retval = -99;
7067
7068     out:
7069       if (vam->retval == -99)
7070         errmsg ("timeout");
7071
7072       if (vam->async_errors > 0)
7073         {
7074           errmsg ("%d asynchronous errors", vam->async_errors);
7075           vam->retval = -98;
7076         }
7077       vam->async_errors = 0;
7078       after = vat_time_now (vam);
7079
7080       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7081              count, after - before, count / (after - before));
7082     }
7083   else
7084     {
7085       int ret;
7086
7087       /* Wait for a reply... */
7088       W (ret);
7089       return ret;
7090     }
7091   /* Return the good/bad news */
7092   return (vam->retval);
7093 }
7094
7095 static int
7096 api_bridge_domain_set_mac_age (vat_main_t * vam)
7097 {
7098   unformat_input_t *i = vam->input;
7099   vl_api_bridge_domain_set_mac_age_t *mp;
7100   u32 bd_id = ~0;
7101   u32 mac_age = 0;
7102   int ret;
7103
7104   /* Parse args required to build the message */
7105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7106     {
7107       if (unformat (i, "bd_id %d", &bd_id));
7108       else if (unformat (i, "mac-age %d", &mac_age));
7109       else
7110         break;
7111     }
7112
7113   if (bd_id == ~0)
7114     {
7115       errmsg ("missing bridge domain");
7116       return -99;
7117     }
7118
7119   if (mac_age > 255)
7120     {
7121       errmsg ("mac age must be less than 256 ");
7122       return -99;
7123     }
7124
7125   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7126
7127   mp->bd_id = htonl (bd_id);
7128   mp->mac_age = (u8) mac_age;
7129
7130   S (mp);
7131   W (ret);
7132   return ret;
7133 }
7134
7135 static int
7136 api_l2_flags (vat_main_t * vam)
7137 {
7138   unformat_input_t *i = vam->input;
7139   vl_api_l2_flags_t *mp;
7140   u32 sw_if_index;
7141   u32 flags = 0;
7142   u8 sw_if_index_set = 0;
7143   u8 is_set = 0;
7144   int ret;
7145
7146   /* Parse args required to build the message */
7147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7148     {
7149       if (unformat (i, "sw_if_index %d", &sw_if_index))
7150         sw_if_index_set = 1;
7151       else if (unformat (i, "sw_if"))
7152         {
7153           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7154             {
7155               if (unformat
7156                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7157                 sw_if_index_set = 1;
7158             }
7159           else
7160             break;
7161         }
7162       else if (unformat (i, "learn"))
7163         flags |= L2_LEARN;
7164       else if (unformat (i, "forward"))
7165         flags |= L2_FWD;
7166       else if (unformat (i, "flood"))
7167         flags |= L2_FLOOD;
7168       else if (unformat (i, "uu-flood"))
7169         flags |= L2_UU_FLOOD;
7170       else if (unformat (i, "arp-term"))
7171         flags |= L2_ARP_TERM;
7172       else if (unformat (i, "off"))
7173         is_set = 0;
7174       else if (unformat (i, "disable"))
7175         is_set = 0;
7176       else
7177         break;
7178     }
7179
7180   if (sw_if_index_set == 0)
7181     {
7182       errmsg ("missing interface name or sw_if_index");
7183       return -99;
7184     }
7185
7186   M (L2_FLAGS, mp);
7187
7188   mp->sw_if_index = ntohl (sw_if_index);
7189   mp->feature_bitmap = ntohl (flags);
7190   mp->is_set = is_set;
7191
7192   S (mp);
7193   W (ret);
7194   return ret;
7195 }
7196
7197 static int
7198 api_bridge_flags (vat_main_t * vam)
7199 {
7200   unformat_input_t *i = vam->input;
7201   vl_api_bridge_flags_t *mp;
7202   u32 bd_id;
7203   u8 bd_id_set = 0;
7204   u8 is_set = 1;
7205   bd_flags_t flags = 0;
7206   int ret;
7207
7208   /* Parse args required to build the message */
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "bd_id %d", &bd_id))
7212         bd_id_set = 1;
7213       else if (unformat (i, "learn"))
7214         flags |= BRIDGE_API_FLAG_LEARN;
7215       else if (unformat (i, "forward"))
7216         flags |= BRIDGE_API_FLAG_FWD;
7217       else if (unformat (i, "flood"))
7218         flags |= BRIDGE_API_FLAG_FLOOD;
7219       else if (unformat (i, "uu-flood"))
7220         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7221       else if (unformat (i, "arp-term"))
7222         flags |= BRIDGE_API_FLAG_ARP_TERM;
7223       else if (unformat (i, "off"))
7224         is_set = 0;
7225       else if (unformat (i, "disable"))
7226         is_set = 0;
7227       else
7228         break;
7229     }
7230
7231   if (bd_id_set == 0)
7232     {
7233       errmsg ("missing bridge domain");
7234       return -99;
7235     }
7236
7237   M (BRIDGE_FLAGS, mp);
7238
7239   mp->bd_id = ntohl (bd_id);
7240   mp->flags = ntohl (flags);
7241   mp->is_set = is_set;
7242
7243   S (mp);
7244   W (ret);
7245   return ret;
7246 }
7247
7248 static int
7249 api_bd_ip_mac_add_del (vat_main_t * vam)
7250 {
7251   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7252   vl_api_mac_address_t mac = { 0 };
7253   unformat_input_t *i = vam->input;
7254   vl_api_bd_ip_mac_add_del_t *mp;
7255   u32 bd_id;
7256   u8 is_add = 1;
7257   u8 bd_id_set = 0;
7258   u8 ip_set = 0;
7259   u8 mac_set = 0;
7260   int ret;
7261
7262
7263   /* Parse args required to build the message */
7264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7265     {
7266       if (unformat (i, "bd_id %d", &bd_id))
7267         {
7268           bd_id_set++;
7269         }
7270       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7271         {
7272           ip_set++;
7273         }
7274       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7275         {
7276           mac_set++;
7277         }
7278       else if (unformat (i, "del"))
7279         is_add = 0;
7280       else
7281         break;
7282     }
7283
7284   if (bd_id_set == 0)
7285     {
7286       errmsg ("missing bridge domain");
7287       return -99;
7288     }
7289   else if (ip_set == 0)
7290     {
7291       errmsg ("missing IP address");
7292       return -99;
7293     }
7294   else if (mac_set == 0)
7295     {
7296       errmsg ("missing MAC address");
7297       return -99;
7298     }
7299
7300   M (BD_IP_MAC_ADD_DEL, mp);
7301
7302   mp->entry.bd_id = ntohl (bd_id);
7303   mp->is_add = is_add;
7304
7305   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7306   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7307
7308   S (mp);
7309   W (ret);
7310   return ret;
7311 }
7312
7313 static int
7314 api_bd_ip_mac_flush (vat_main_t * vam)
7315 {
7316   unformat_input_t *i = vam->input;
7317   vl_api_bd_ip_mac_flush_t *mp;
7318   u32 bd_id;
7319   u8 bd_id_set = 0;
7320   int ret;
7321
7322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7323     {
7324       if (unformat (i, "bd_id %d", &bd_id))
7325         {
7326           bd_id_set++;
7327         }
7328       else
7329         break;
7330     }
7331
7332   if (bd_id_set == 0)
7333     {
7334       errmsg ("missing bridge domain");
7335       return -99;
7336     }
7337
7338   M (BD_IP_MAC_FLUSH, mp);
7339
7340   mp->bd_id = ntohl (bd_id);
7341
7342   S (mp);
7343   W (ret);
7344   return ret;
7345 }
7346
7347 static void vl_api_bd_ip_mac_details_t_handler
7348   (vl_api_bd_ip_mac_details_t * mp)
7349 {
7350   vat_main_t *vam = &vat_main;
7351
7352   print (vam->ofp,
7353          "\n%-5d %U %U",
7354          ntohl (mp->entry.bd_id),
7355          format_vl_api_mac_address, mp->entry.mac,
7356          format_vl_api_address, &mp->entry.ip);
7357 }
7358
7359 static void vl_api_bd_ip_mac_details_t_handler_json
7360   (vl_api_bd_ip_mac_details_t * mp)
7361 {
7362   vat_main_t *vam = &vat_main;
7363   vat_json_node_t *node = NULL;
7364
7365   if (VAT_JSON_ARRAY != vam->json_tree.type)
7366     {
7367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7368       vat_json_init_array (&vam->json_tree);
7369     }
7370   node = vat_json_array_add (&vam->json_tree);
7371
7372   vat_json_init_object (node);
7373   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7374   vat_json_object_add_string_copy (node, "mac_address",
7375                                    format (0, "%U", format_vl_api_mac_address,
7376                                            &mp->entry.mac));
7377   u8 *ip = 0;
7378
7379   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7380   vat_json_object_add_string_copy (node, "ip_address", ip);
7381   vec_free (ip);
7382 }
7383
7384 static int
7385 api_bd_ip_mac_dump (vat_main_t * vam)
7386 {
7387   unformat_input_t *i = vam->input;
7388   vl_api_bd_ip_mac_dump_t *mp;
7389   vl_api_control_ping_t *mp_ping;
7390   int ret;
7391   u32 bd_id;
7392   u8 bd_id_set = 0;
7393
7394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395     {
7396       if (unformat (i, "bd_id %d", &bd_id))
7397         {
7398           bd_id_set++;
7399         }
7400       else
7401         break;
7402     }
7403
7404   print (vam->ofp,
7405          "\n%-5s %-7s %-20s %-30s",
7406          "bd_id", "is_ipv6", "mac_address", "ip_address");
7407
7408   /* Dump Bridge Domain Ip to Mac entries */
7409   M (BD_IP_MAC_DUMP, mp);
7410
7411   if (bd_id_set)
7412     mp->bd_id = htonl (bd_id);
7413   else
7414     mp->bd_id = ~0;
7415
7416   S (mp);
7417
7418   /* Use a control ping for synchronization */
7419   MPING (CONTROL_PING, mp_ping);
7420   S (mp_ping);
7421
7422   W (ret);
7423   return ret;
7424 }
7425
7426 static int
7427 api_tap_create_v2 (vat_main_t * vam)
7428 {
7429   unformat_input_t *i = vam->input;
7430   vl_api_tap_create_v2_t *mp;
7431 #define TAP_FLAG_GSO (1 << 0)
7432   u8 mac_address[6];
7433   u8 random_mac = 1;
7434   u32 id = ~0;
7435   u8 *host_if_name = 0;
7436   u8 *host_ns = 0;
7437   u8 host_mac_addr[6];
7438   u8 host_mac_addr_set = 0;
7439   u8 *host_bridge = 0;
7440   ip4_address_t host_ip4_addr;
7441   ip4_address_t host_ip4_gw;
7442   u8 host_ip4_gw_set = 0;
7443   u32 host_ip4_prefix_len = 0;
7444   ip6_address_t host_ip6_addr;
7445   ip6_address_t host_ip6_gw;
7446   u8 host_ip6_gw_set = 0;
7447   u32 host_ip6_prefix_len = 0;
7448   u8 host_mtu_set = 0;
7449   u32 host_mtu_size = 0;
7450   u32 tap_flags = 0;
7451   int ret;
7452   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7453
7454   clib_memset (mac_address, 0, sizeof (mac_address));
7455
7456   /* Parse args required to build the message */
7457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7458     {
7459       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7460         {
7461           random_mac = 0;
7462         }
7463       else if (unformat (i, "id %u", &id))
7464         ;
7465       else if (unformat (i, "host-if-name %s", &host_if_name))
7466         ;
7467       else if (unformat (i, "host-ns %s", &host_ns))
7468         ;
7469       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7470                          host_mac_addr))
7471         host_mac_addr_set = 1;
7472       else if (unformat (i, "host-bridge %s", &host_bridge))
7473         ;
7474       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7475                          &host_ip4_addr, &host_ip4_prefix_len))
7476         ;
7477       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7478                          &host_ip6_addr, &host_ip6_prefix_len))
7479         ;
7480       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7481                          &host_ip4_gw))
7482         host_ip4_gw_set = 1;
7483       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7484                          &host_ip6_gw))
7485         host_ip6_gw_set = 1;
7486       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7487         ;
7488       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7489         ;
7490       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7491         host_mtu_set = 1;
7492       else if (unformat (i, "no-gso"))
7493         tap_flags &= ~TAP_FLAG_GSO;
7494       else if (unformat (i, "gso"))
7495         tap_flags |= TAP_FLAG_GSO;
7496       else
7497         break;
7498     }
7499
7500   if (vec_len (host_if_name) > 63)
7501     {
7502       errmsg ("tap name too long. ");
7503       return -99;
7504     }
7505   if (vec_len (host_ns) > 63)
7506     {
7507       errmsg ("host name space too long. ");
7508       return -99;
7509     }
7510   if (vec_len (host_bridge) > 63)
7511     {
7512       errmsg ("host bridge name too long. ");
7513       return -99;
7514     }
7515   if (host_ip4_prefix_len > 32)
7516     {
7517       errmsg ("host ip4 prefix length not valid. ");
7518       return -99;
7519     }
7520   if (host_ip6_prefix_len > 128)
7521     {
7522       errmsg ("host ip6 prefix length not valid. ");
7523       return -99;
7524     }
7525   if (!is_pow2 (rx_ring_sz))
7526     {
7527       errmsg ("rx ring size must be power of 2. ");
7528       return -99;
7529     }
7530   if (rx_ring_sz > 32768)
7531     {
7532       errmsg ("rx ring size must be 32768 or lower. ");
7533       return -99;
7534     }
7535   if (!is_pow2 (tx_ring_sz))
7536     {
7537       errmsg ("tx ring size must be power of 2. ");
7538       return -99;
7539     }
7540   if (tx_ring_sz > 32768)
7541     {
7542       errmsg ("tx ring size must be 32768 or lower. ");
7543       return -99;
7544     }
7545   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7546     {
7547       errmsg ("host MTU size must be in between 64 and 65355. ");
7548       return -99;
7549     }
7550
7551   /* Construct the API message */
7552   M (TAP_CREATE_V2, mp);
7553
7554   mp->use_random_mac = random_mac;
7555
7556   mp->id = ntohl (id);
7557   mp->host_namespace_set = host_ns != 0;
7558   mp->host_bridge_set = host_bridge != 0;
7559   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7560   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7561   mp->rx_ring_sz = ntohs (rx_ring_sz);
7562   mp->tx_ring_sz = ntohs (tx_ring_sz);
7563   mp->host_mtu_set = host_mtu_set;
7564   mp->host_mtu_size = ntohl (host_mtu_size);
7565   mp->tap_flags = ntohl (tap_flags);
7566
7567   if (random_mac == 0)
7568     clib_memcpy (mp->mac_address, mac_address, 6);
7569   if (host_mac_addr_set)
7570     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7571   if (host_if_name)
7572     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7573   if (host_ns)
7574     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7575   if (host_bridge)
7576     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7577   if (host_ip4_prefix_len)
7578     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7579   if (host_ip6_prefix_len)
7580     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7581   if (host_ip4_gw_set)
7582     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7583   if (host_ip6_gw_set)
7584     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7585
7586   vec_free (host_ns);
7587   vec_free (host_if_name);
7588   vec_free (host_bridge);
7589
7590   /* send it... */
7591   S (mp);
7592
7593   /* Wait for a reply... */
7594   W (ret);
7595   return ret;
7596 }
7597
7598 static int
7599 api_tap_delete_v2 (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_tap_delete_v2_t *mp;
7603   u32 sw_if_index = ~0;
7604   u8 sw_if_index_set = 0;
7605   int ret;
7606
7607   /* Parse args required to build the message */
7608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7609     {
7610       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7611         sw_if_index_set = 1;
7612       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7613         sw_if_index_set = 1;
7614       else
7615         break;
7616     }
7617
7618   if (sw_if_index_set == 0)
7619     {
7620       errmsg ("missing vpp interface name. ");
7621       return -99;
7622     }
7623
7624   /* Construct the API message */
7625   M (TAP_DELETE_V2, mp);
7626
7627   mp->sw_if_index = ntohl (sw_if_index);
7628
7629   /* send it... */
7630   S (mp);
7631
7632   /* Wait for a reply... */
7633   W (ret);
7634   return ret;
7635 }
7636
7637 uword
7638 unformat_pci_addr (unformat_input_t * input, va_list * args)
7639 {
7640   struct pci_addr_t
7641   {
7642     u16 domain;
7643     u8 bus;
7644     u8 slot:5;
7645     u8 function:3;
7646   } *addr;
7647   addr = va_arg (*args, struct pci_addr_t *);
7648   u32 x[4];
7649
7650   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7651     return 0;
7652
7653   addr->domain = x[0];
7654   addr->bus = x[1];
7655   addr->slot = x[2];
7656   addr->function = x[3];
7657
7658   return 1;
7659 }
7660
7661 static int
7662 api_virtio_pci_create (vat_main_t * vam)
7663 {
7664   unformat_input_t *i = vam->input;
7665   vl_api_virtio_pci_create_t *mp;
7666   u8 mac_address[6];
7667   u8 random_mac = 1;
7668   u8 gso_enabled = 0;
7669   u32 pci_addr = 0;
7670   u64 features = (u64) ~ (0ULL);
7671   int ret;
7672
7673   clib_memset (mac_address, 0, sizeof (mac_address));
7674
7675   /* Parse args required to build the message */
7676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7677     {
7678       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7679         {
7680           random_mac = 0;
7681         }
7682       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7683         ;
7684       else if (unformat (i, "features 0x%llx", &features))
7685         ;
7686       else if (unformat (i, "gso-enabled"))
7687         gso_enabled = 1;
7688       else
7689         break;
7690     }
7691
7692   if (pci_addr == 0)
7693     {
7694       errmsg ("pci address must be non zero. ");
7695       return -99;
7696     }
7697
7698   /* Construct the API message */
7699   M (VIRTIO_PCI_CREATE, mp);
7700
7701   mp->use_random_mac = random_mac;
7702
7703   mp->pci_addr = htonl (pci_addr);
7704   mp->features = clib_host_to_net_u64 (features);
7705   mp->gso_enabled = gso_enabled;
7706
7707   if (random_mac == 0)
7708     clib_memcpy (mp->mac_address, mac_address, 6);
7709
7710   /* send it... */
7711   S (mp);
7712
7713   /* Wait for a reply... */
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_virtio_pci_delete (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_virtio_pci_delete_t *mp;
7723   u32 sw_if_index = ~0;
7724   u8 sw_if_index_set = 0;
7725   int ret;
7726
7727   /* Parse args required to build the message */
7728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7729     {
7730       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7731         sw_if_index_set = 1;
7732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7733         sw_if_index_set = 1;
7734       else
7735         break;
7736     }
7737
7738   if (sw_if_index_set == 0)
7739     {
7740       errmsg ("missing vpp interface name. ");
7741       return -99;
7742     }
7743
7744   /* Construct the API message */
7745   M (VIRTIO_PCI_DELETE, mp);
7746
7747   mp->sw_if_index = htonl (sw_if_index);
7748
7749   /* send it... */
7750   S (mp);
7751
7752   /* Wait for a reply... */
7753   W (ret);
7754   return ret;
7755 }
7756
7757 static int
7758 api_bond_create (vat_main_t * vam)
7759 {
7760   unformat_input_t *i = vam->input;
7761   vl_api_bond_create_t *mp;
7762   u8 mac_address[6];
7763   u8 custom_mac = 0;
7764   int ret;
7765   u8 mode;
7766   u8 lb;
7767   u8 mode_is_set = 0;
7768   u32 id = ~0;
7769
7770   clib_memset (mac_address, 0, sizeof (mac_address));
7771   lb = BOND_LB_L2;
7772
7773   /* Parse args required to build the message */
7774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7775     {
7776       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7777         mode_is_set = 1;
7778       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7779                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7780         ;
7781       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7782                          mac_address))
7783         custom_mac = 1;
7784       else if (unformat (i, "id %u", &id))
7785         ;
7786       else
7787         break;
7788     }
7789
7790   if (mode_is_set == 0)
7791     {
7792       errmsg ("Missing bond mode. ");
7793       return -99;
7794     }
7795
7796   /* Construct the API message */
7797   M (BOND_CREATE, mp);
7798
7799   mp->use_custom_mac = custom_mac;
7800
7801   mp->mode = mode;
7802   mp->lb = lb;
7803   mp->id = htonl (id);
7804
7805   if (custom_mac)
7806     clib_memcpy (mp->mac_address, mac_address, 6);
7807
7808   /* send it... */
7809   S (mp);
7810
7811   /* Wait for a reply... */
7812   W (ret);
7813   return ret;
7814 }
7815
7816 static int
7817 api_bond_delete (vat_main_t * vam)
7818 {
7819   unformat_input_t *i = vam->input;
7820   vl_api_bond_delete_t *mp;
7821   u32 sw_if_index = ~0;
7822   u8 sw_if_index_set = 0;
7823   int ret;
7824
7825   /* Parse args required to build the message */
7826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7827     {
7828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7829         sw_if_index_set = 1;
7830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7831         sw_if_index_set = 1;
7832       else
7833         break;
7834     }
7835
7836   if (sw_if_index_set == 0)
7837     {
7838       errmsg ("missing vpp interface name. ");
7839       return -99;
7840     }
7841
7842   /* Construct the API message */
7843   M (BOND_DELETE, mp);
7844
7845   mp->sw_if_index = ntohl (sw_if_index);
7846
7847   /* send it... */
7848   S (mp);
7849
7850   /* Wait for a reply... */
7851   W (ret);
7852   return ret;
7853 }
7854
7855 static int
7856 api_bond_enslave (vat_main_t * vam)
7857 {
7858   unformat_input_t *i = vam->input;
7859   vl_api_bond_enslave_t *mp;
7860   u32 bond_sw_if_index;
7861   int ret;
7862   u8 is_passive;
7863   u8 is_long_timeout;
7864   u32 bond_sw_if_index_is_set = 0;
7865   u32 sw_if_index;
7866   u8 sw_if_index_is_set = 0;
7867
7868   /* Parse args required to build the message */
7869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (unformat (i, "sw_if_index %d", &sw_if_index))
7872         sw_if_index_is_set = 1;
7873       else if (unformat (i, "bond %u", &bond_sw_if_index))
7874         bond_sw_if_index_is_set = 1;
7875       else if (unformat (i, "passive %d", &is_passive))
7876         ;
7877       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7878         ;
7879       else
7880         break;
7881     }
7882
7883   if (bond_sw_if_index_is_set == 0)
7884     {
7885       errmsg ("Missing bond sw_if_index. ");
7886       return -99;
7887     }
7888   if (sw_if_index_is_set == 0)
7889     {
7890       errmsg ("Missing slave sw_if_index. ");
7891       return -99;
7892     }
7893
7894   /* Construct the API message */
7895   M (BOND_ENSLAVE, mp);
7896
7897   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7898   mp->sw_if_index = ntohl (sw_if_index);
7899   mp->is_long_timeout = is_long_timeout;
7900   mp->is_passive = is_passive;
7901
7902   /* send it... */
7903   S (mp);
7904
7905   /* Wait for a reply... */
7906   W (ret);
7907   return ret;
7908 }
7909
7910 static int
7911 api_bond_detach_slave (vat_main_t * vam)
7912 {
7913   unformat_input_t *i = vam->input;
7914   vl_api_bond_detach_slave_t *mp;
7915   u32 sw_if_index = ~0;
7916   u8 sw_if_index_set = 0;
7917   int ret;
7918
7919   /* Parse args required to build the message */
7920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7921     {
7922       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7923         sw_if_index_set = 1;
7924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7925         sw_if_index_set = 1;
7926       else
7927         break;
7928     }
7929
7930   if (sw_if_index_set == 0)
7931     {
7932       errmsg ("missing vpp interface name. ");
7933       return -99;
7934     }
7935
7936   /* Construct the API message */
7937   M (BOND_DETACH_SLAVE, mp);
7938
7939   mp->sw_if_index = ntohl (sw_if_index);
7940
7941   /* send it... */
7942   S (mp);
7943
7944   /* Wait for a reply... */
7945   W (ret);
7946   return ret;
7947 }
7948
7949 static int
7950 api_ip_table_add_del (vat_main_t * vam)
7951 {
7952   unformat_input_t *i = vam->input;
7953   vl_api_ip_table_add_del_t *mp;
7954   u32 table_id = ~0;
7955   u8 is_ipv6 = 0;
7956   u8 is_add = 1;
7957   int ret = 0;
7958
7959   /* Parse args required to build the message */
7960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7961     {
7962       if (unformat (i, "ipv6"))
7963         is_ipv6 = 1;
7964       else if (unformat (i, "del"))
7965         is_add = 0;
7966       else if (unformat (i, "add"))
7967         is_add = 1;
7968       else if (unformat (i, "table %d", &table_id))
7969         ;
7970       else
7971         {
7972           clib_warning ("parse error '%U'", format_unformat_error, i);
7973           return -99;
7974         }
7975     }
7976
7977   if (~0 == table_id)
7978     {
7979       errmsg ("missing table-ID");
7980       return -99;
7981     }
7982
7983   /* Construct the API message */
7984   M (IP_TABLE_ADD_DEL, mp);
7985
7986   mp->table.table_id = ntohl (table_id);
7987   mp->table.is_ip6 = is_ipv6;
7988   mp->is_add = is_add;
7989
7990   /* send it... */
7991   S (mp);
7992
7993   /* Wait for a reply... */
7994   W (ret);
7995
7996   return ret;
7997 }
7998
7999 uword
8000 unformat_fib_path (unformat_input_t * input, va_list * args)
8001 {
8002   vat_main_t *vam = va_arg (*args, vat_main_t *);
8003   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8004   u32 weight, preference;
8005   mpls_label_t out_label;
8006
8007   clib_memset (path, 0, sizeof (*path));
8008   path->weight = 1;
8009   path->sw_if_index = ~0;
8010   path->rpf_id = ~0;
8011   path->n_labels = 0;
8012
8013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8014     {
8015       if (unformat (input, "%U %U",
8016                     unformat_vl_api_ip4_address,
8017                     &path->nh.address.ip4,
8018                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8019         {
8020           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8021         }
8022       else if (unformat (input, "%U %U",
8023                          unformat_vl_api_ip6_address,
8024                          &path->nh.address.ip6,
8025                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8026         {
8027           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8028         }
8029       else if (unformat (input, "weight %u", &weight))
8030         {
8031           path->weight = weight;
8032         }
8033       else if (unformat (input, "preference %u", &preference))
8034         {
8035           path->preference = preference;
8036         }
8037       else if (unformat (input, "%U next-hop-table %d",
8038                          unformat_vl_api_ip4_address,
8039                          &path->nh.address.ip4, &path->table_id))
8040         {
8041           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8042         }
8043       else if (unformat (input, "%U next-hop-table %d",
8044                          unformat_vl_api_ip6_address,
8045                          &path->nh.address.ip6, &path->table_id))
8046         {
8047           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8048         }
8049       else if (unformat (input, "%U",
8050                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8051         {
8052           /*
8053            * the recursive next-hops are by default in the default table
8054            */
8055           path->table_id = 0;
8056           path->sw_if_index = ~0;
8057           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8058         }
8059       else if (unformat (input, "%U",
8060                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8061         {
8062           /*
8063            * the recursive next-hops are by default in the default table
8064            */
8065           path->table_id = 0;
8066           path->sw_if_index = ~0;
8067           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8068         }
8069       else if (unformat (input, "resolve-via-host"))
8070         {
8071           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8072         }
8073       else if (unformat (input, "resolve-via-attached"))
8074         {
8075           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8076         }
8077       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8078         {
8079           path->type = FIB_API_PATH_TYPE_LOCAL;
8080           path->sw_if_index = ~0;
8081           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8082         }
8083       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8084         {
8085           path->type = FIB_API_PATH_TYPE_LOCAL;
8086           path->sw_if_index = ~0;
8087           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8088         }
8089       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8090         ;
8091       else if (unformat (input, "via-label %d", &path->nh.via_label))
8092         {
8093           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8094           path->sw_if_index = ~0;
8095         }
8096       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8097         {
8098           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8099           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8100         }
8101       else if (unformat (input, "local"))
8102         {
8103           path->type = FIB_API_PATH_TYPE_LOCAL;
8104         }
8105       else if (unformat (input, "out-labels"))
8106         {
8107           while (unformat (input, "%d", &out_label))
8108             {
8109               path->label_stack[path->n_labels].label = out_label;
8110               path->label_stack[path->n_labels].is_uniform = 0;
8111               path->label_stack[path->n_labels].ttl = 64;
8112               path->n_labels++;
8113             }
8114         }
8115       else if (unformat (input, "via"))
8116         {
8117           /* new path, back up and return */
8118           unformat_put_input (input);
8119           unformat_put_input (input);
8120           unformat_put_input (input);
8121           unformat_put_input (input);
8122           break;
8123         }
8124       else
8125         {
8126           return (0);
8127         }
8128     }
8129
8130   path->proto = ntohl (path->proto);
8131   path->type = ntohl (path->type);
8132   path->flags = ntohl (path->flags);
8133   path->table_id = ntohl (path->table_id);
8134   path->sw_if_index = ntohl (path->sw_if_index);
8135
8136   return (1);
8137 }
8138
8139 static int
8140 api_ip_route_add_del (vat_main_t * vam)
8141 {
8142   unformat_input_t *i = vam->input;
8143   vl_api_ip_route_add_del_t *mp;
8144   u32 vrf_id = 0;
8145   u8 is_add = 1;
8146   u8 is_multipath = 0;
8147   u8 prefix_set = 0;
8148   u8 path_count = 0;
8149   vl_api_prefix_t pfx = { };
8150   vl_api_fib_path_t paths[8];
8151   int count = 1;
8152   int j;
8153   f64 before = 0;
8154   u32 random_add_del = 0;
8155   u32 *random_vector = 0;
8156   u32 random_seed = 0xdeaddabe;
8157
8158   /* Parse args required to build the message */
8159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8160     {
8161       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8162         prefix_set = 1;
8163       else if (unformat (i, "del"))
8164         is_add = 0;
8165       else if (unformat (i, "add"))
8166         is_add = 1;
8167       else if (unformat (i, "vrf %d", &vrf_id))
8168         ;
8169       else if (unformat (i, "count %d", &count))
8170         ;
8171       else if (unformat (i, "random"))
8172         random_add_del = 1;
8173       else if (unformat (i, "multipath"))
8174         is_multipath = 1;
8175       else if (unformat (i, "seed %d", &random_seed))
8176         ;
8177       else
8178         if (unformat
8179             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8180         {
8181           path_count++;
8182           if (8 == path_count)
8183             {
8184               errmsg ("max 8 paths");
8185               return -99;
8186             }
8187         }
8188       else
8189         {
8190           clib_warning ("parse error '%U'", format_unformat_error, i);
8191           return -99;
8192         }
8193     }
8194
8195   if (!path_count)
8196     {
8197       errmsg ("specify a path; via ...");
8198       return -99;
8199     }
8200   if (prefix_set == 0)
8201     {
8202       errmsg ("missing prefix");
8203       return -99;
8204     }
8205
8206   /* Generate a pile of unique, random routes */
8207   if (random_add_del)
8208     {
8209       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8210       u32 this_random_address;
8211       uword *random_hash;
8212
8213       random_hash = hash_create (count, sizeof (uword));
8214
8215       hash_set (random_hash, i->as_u32, 1);
8216       for (j = 0; j <= count; j++)
8217         {
8218           do
8219             {
8220               this_random_address = random_u32 (&random_seed);
8221               this_random_address =
8222                 clib_host_to_net_u32 (this_random_address);
8223             }
8224           while (hash_get (random_hash, this_random_address));
8225           vec_add1 (random_vector, this_random_address);
8226           hash_set (random_hash, this_random_address, 1);
8227         }
8228       hash_free (random_hash);
8229       set_ip4_address (&pfx.address, random_vector[0]);
8230     }
8231
8232   if (count > 1)
8233     {
8234       /* Turn on async mode */
8235       vam->async_mode = 1;
8236       vam->async_errors = 0;
8237       before = vat_time_now (vam);
8238     }
8239
8240   for (j = 0; j < count; j++)
8241     {
8242       /* Construct the API message */
8243       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8244
8245       mp->is_add = is_add;
8246       mp->is_multipath = is_multipath;
8247
8248       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8249       mp->route.table_id = ntohl (vrf_id);
8250       mp->route.n_paths = path_count;
8251
8252       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8253
8254       if (random_add_del)
8255         set_ip4_address (&pfx.address, random_vector[j + 1]);
8256       else
8257         increment_address (&pfx.address);
8258       /* send it... */
8259       S (mp);
8260       /* If we receive SIGTERM, stop now... */
8261       if (vam->do_exit)
8262         break;
8263     }
8264
8265   /* When testing multiple add/del ops, use a control-ping to sync */
8266   if (count > 1)
8267     {
8268       vl_api_control_ping_t *mp_ping;
8269       f64 after;
8270       f64 timeout;
8271
8272       /* Shut off async mode */
8273       vam->async_mode = 0;
8274
8275       MPING (CONTROL_PING, mp_ping);
8276       S (mp_ping);
8277
8278       timeout = vat_time_now (vam) + 1.0;
8279       while (vat_time_now (vam) < timeout)
8280         if (vam->result_ready == 1)
8281           goto out;
8282       vam->retval = -99;
8283
8284     out:
8285       if (vam->retval == -99)
8286         errmsg ("timeout");
8287
8288       if (vam->async_errors > 0)
8289         {
8290           errmsg ("%d asynchronous errors", vam->async_errors);
8291           vam->retval = -98;
8292         }
8293       vam->async_errors = 0;
8294       after = vat_time_now (vam);
8295
8296       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8297       if (j > 0)
8298         count = j;
8299
8300       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8301              count, after - before, count / (after - before));
8302     }
8303   else
8304     {
8305       int ret;
8306
8307       /* Wait for a reply... */
8308       W (ret);
8309       return ret;
8310     }
8311
8312   /* Return the good/bad news */
8313   return (vam->retval);
8314 }
8315
8316 static int
8317 api_ip_mroute_add_del (vat_main_t * vam)
8318 {
8319   unformat_input_t *i = vam->input;
8320   u8 path_set = 0, prefix_set = 0, is_add = 1;
8321   vl_api_ip_mroute_add_del_t *mp;
8322   mfib_entry_flags_t eflags = 0;
8323   vl_api_mfib_path_t path;
8324   vl_api_mprefix_t pfx = { };
8325   u32 vrf_id = 0;
8326   int ret;
8327
8328   /* Parse args required to build the message */
8329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8330     {
8331       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8332         {
8333           prefix_set = 1;
8334           pfx.grp_address_length = htons (pfx.grp_address_length);
8335         }
8336       else if (unformat (i, "del"))
8337         is_add = 0;
8338       else if (unformat (i, "add"))
8339         is_add = 1;
8340       else if (unformat (i, "vrf %d", &vrf_id))
8341         ;
8342       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8343         path.itf_flags = htonl (path.itf_flags);
8344       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8345         ;
8346       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8347         path_set = 1;
8348       else
8349         {
8350           clib_warning ("parse error '%U'", format_unformat_error, i);
8351           return -99;
8352         }
8353     }
8354
8355   if (prefix_set == 0)
8356     {
8357       errmsg ("missing addresses\n");
8358       return -99;
8359     }
8360   if (path_set == 0)
8361     {
8362       errmsg ("missing path\n");
8363       return -99;
8364     }
8365
8366   /* Construct the API message */
8367   M (IP_MROUTE_ADD_DEL, mp);
8368
8369   mp->is_add = is_add;
8370   mp->is_multipath = 1;
8371
8372   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8373   mp->route.table_id = htonl (vrf_id);
8374   mp->route.n_paths = 1;
8375   mp->route.entry_flags = htonl (eflags);
8376
8377   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8378
8379   /* send it... */
8380   S (mp);
8381   /* Wait for a reply... */
8382   W (ret);
8383   return ret;
8384 }
8385
8386 static int
8387 api_mpls_table_add_del (vat_main_t * vam)
8388 {
8389   unformat_input_t *i = vam->input;
8390   vl_api_mpls_table_add_del_t *mp;
8391   u32 table_id = ~0;
8392   u8 is_add = 1;
8393   int ret = 0;
8394
8395   /* Parse args required to build the message */
8396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (i, "table %d", &table_id))
8399         ;
8400       else if (unformat (i, "del"))
8401         is_add = 0;
8402       else if (unformat (i, "add"))
8403         is_add = 1;
8404       else
8405         {
8406           clib_warning ("parse error '%U'", format_unformat_error, i);
8407           return -99;
8408         }
8409     }
8410
8411   if (~0 == table_id)
8412     {
8413       errmsg ("missing table-ID");
8414       return -99;
8415     }
8416
8417   /* Construct the API message */
8418   M (MPLS_TABLE_ADD_DEL, mp);
8419
8420   mp->mt_table.mt_table_id = ntohl (table_id);
8421   mp->mt_is_add = is_add;
8422
8423   /* send it... */
8424   S (mp);
8425
8426   /* Wait for a reply... */
8427   W (ret);
8428
8429   return ret;
8430 }
8431
8432 static int
8433 api_mpls_route_add_del (vat_main_t * vam)
8434 {
8435   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8436   mpls_label_t local_label = MPLS_LABEL_INVALID;
8437   unformat_input_t *i = vam->input;
8438   vl_api_mpls_route_add_del_t *mp;
8439   vl_api_fib_path_t paths[8];
8440   int count = 1, j;
8441   f64 before = 0;
8442
8443   /* Parse args required to build the message */
8444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8445     {
8446       if (unformat (i, "%d", &local_label))
8447         ;
8448       else if (unformat (i, "eos"))
8449         is_eos = 1;
8450       else if (unformat (i, "non-eos"))
8451         is_eos = 0;
8452       else if (unformat (i, "del"))
8453         is_add = 0;
8454       else if (unformat (i, "add"))
8455         is_add = 1;
8456       else if (unformat (i, "multipath"))
8457         is_multipath = 1;
8458       else if (unformat (i, "count %d", &count))
8459         ;
8460       else
8461         if (unformat
8462             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8463         {
8464           path_count++;
8465           if (8 == path_count)
8466             {
8467               errmsg ("max 8 paths");
8468               return -99;
8469             }
8470         }
8471       else
8472         {
8473           clib_warning ("parse error '%U'", format_unformat_error, i);
8474           return -99;
8475         }
8476     }
8477
8478   if (!path_count)
8479     {
8480       errmsg ("specify a path; via ...");
8481       return -99;
8482     }
8483
8484   if (MPLS_LABEL_INVALID == local_label)
8485     {
8486       errmsg ("missing label");
8487       return -99;
8488     }
8489
8490   if (count > 1)
8491     {
8492       /* Turn on async mode */
8493       vam->async_mode = 1;
8494       vam->async_errors = 0;
8495       before = vat_time_now (vam);
8496     }
8497
8498   for (j = 0; j < count; j++)
8499     {
8500       /* Construct the API message */
8501       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8502
8503       mp->mr_is_add = is_add;
8504       mp->mr_is_multipath = is_multipath;
8505
8506       mp->mr_route.mr_label = local_label;
8507       mp->mr_route.mr_eos = is_eos;
8508       mp->mr_route.mr_table_id = 0;
8509       mp->mr_route.mr_n_paths = path_count;
8510
8511       clib_memcpy (&mp->mr_route.mr_paths, paths,
8512                    sizeof (paths[0]) * path_count);
8513
8514       local_label++;
8515
8516       /* send it... */
8517       S (mp);
8518       /* If we receive SIGTERM, stop now... */
8519       if (vam->do_exit)
8520         break;
8521     }
8522
8523   /* When testing multiple add/del ops, use a control-ping to sync */
8524   if (count > 1)
8525     {
8526       vl_api_control_ping_t *mp_ping;
8527       f64 after;
8528       f64 timeout;
8529
8530       /* Shut off async mode */
8531       vam->async_mode = 0;
8532
8533       MPING (CONTROL_PING, mp_ping);
8534       S (mp_ping);
8535
8536       timeout = vat_time_now (vam) + 1.0;
8537       while (vat_time_now (vam) < timeout)
8538         if (vam->result_ready == 1)
8539           goto out;
8540       vam->retval = -99;
8541
8542     out:
8543       if (vam->retval == -99)
8544         errmsg ("timeout");
8545
8546       if (vam->async_errors > 0)
8547         {
8548           errmsg ("%d asynchronous errors", vam->async_errors);
8549           vam->retval = -98;
8550         }
8551       vam->async_errors = 0;
8552       after = vat_time_now (vam);
8553
8554       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8555       if (j > 0)
8556         count = j;
8557
8558       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8559              count, after - before, count / (after - before));
8560     }
8561   else
8562     {
8563       int ret;
8564
8565       /* Wait for a reply... */
8566       W (ret);
8567       return ret;
8568     }
8569
8570   /* Return the good/bad news */
8571   return (vam->retval);
8572   return (0);
8573 }
8574
8575 static int
8576 api_mpls_ip_bind_unbind (vat_main_t * vam)
8577 {
8578   unformat_input_t *i = vam->input;
8579   vl_api_mpls_ip_bind_unbind_t *mp;
8580   u32 ip_table_id = 0;
8581   u8 is_bind = 1;
8582   vl_api_prefix_t pfx;
8583   u8 prefix_set = 0;
8584   mpls_label_t local_label = MPLS_LABEL_INVALID;
8585   int ret;
8586
8587   /* Parse args required to build the message */
8588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8589     {
8590       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8591         prefix_set = 1;
8592       else if (unformat (i, "%d", &local_label))
8593         ;
8594       else if (unformat (i, "table-id %d", &ip_table_id))
8595         ;
8596       else if (unformat (i, "unbind"))
8597         is_bind = 0;
8598       else if (unformat (i, "bind"))
8599         is_bind = 1;
8600       else
8601         {
8602           clib_warning ("parse error '%U'", format_unformat_error, i);
8603           return -99;
8604         }
8605     }
8606
8607   if (!prefix_set)
8608     {
8609       errmsg ("IP prefix not set");
8610       return -99;
8611     }
8612
8613   if (MPLS_LABEL_INVALID == local_label)
8614     {
8615       errmsg ("missing label");
8616       return -99;
8617     }
8618
8619   /* Construct the API message */
8620   M (MPLS_IP_BIND_UNBIND, mp);
8621
8622   mp->mb_is_bind = is_bind;
8623   mp->mb_ip_table_id = ntohl (ip_table_id);
8624   mp->mb_mpls_table_id = 0;
8625   mp->mb_label = ntohl (local_label);
8626   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8627
8628   /* send it... */
8629   S (mp);
8630
8631   /* Wait for a reply... */
8632   W (ret);
8633   return ret;
8634   return (0);
8635 }
8636
8637 static int
8638 api_sr_mpls_policy_add (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_sr_mpls_policy_add_t *mp;
8642   u32 bsid = 0;
8643   u32 weight = 1;
8644   u8 type = 0;
8645   u8 n_segments = 0;
8646   u32 sid;
8647   u32 *segments = NULL;
8648   int ret;
8649
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "bsid %d", &bsid))
8654         ;
8655       else if (unformat (i, "weight %d", &weight))
8656         ;
8657       else if (unformat (i, "spray"))
8658         type = 1;
8659       else if (unformat (i, "next %d", &sid))
8660         {
8661           n_segments += 1;
8662           vec_add1 (segments, htonl (sid));
8663         }
8664       else
8665         {
8666           clib_warning ("parse error '%U'", format_unformat_error, i);
8667           return -99;
8668         }
8669     }
8670
8671   if (bsid == 0)
8672     {
8673       errmsg ("bsid not set");
8674       return -99;
8675     }
8676
8677   if (n_segments == 0)
8678     {
8679       errmsg ("no sid in segment stack");
8680       return -99;
8681     }
8682
8683   /* Construct the API message */
8684   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8685
8686   mp->bsid = htonl (bsid);
8687   mp->weight = htonl (weight);
8688   mp->type = type;
8689   mp->n_segments = n_segments;
8690   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8691   vec_free (segments);
8692
8693   /* send it... */
8694   S (mp);
8695
8696   /* Wait for a reply... */
8697   W (ret);
8698   return ret;
8699 }
8700
8701 static int
8702 api_sr_mpls_policy_del (vat_main_t * vam)
8703 {
8704   unformat_input_t *i = vam->input;
8705   vl_api_sr_mpls_policy_del_t *mp;
8706   u32 bsid = 0;
8707   int ret;
8708
8709   /* Parse args required to build the message */
8710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8711     {
8712       if (unformat (i, "bsid %d", &bsid))
8713         ;
8714       else
8715         {
8716           clib_warning ("parse error '%U'", format_unformat_error, i);
8717           return -99;
8718         }
8719     }
8720
8721   if (bsid == 0)
8722     {
8723       errmsg ("bsid not set");
8724       return -99;
8725     }
8726
8727   /* Construct the API message */
8728   M (SR_MPLS_POLICY_DEL, mp);
8729
8730   mp->bsid = htonl (bsid);
8731
8732   /* send it... */
8733   S (mp);
8734
8735   /* Wait for a reply... */
8736   W (ret);
8737   return ret;
8738 }
8739
8740 static int
8741 api_bier_table_add_del (vat_main_t * vam)
8742 {
8743   unformat_input_t *i = vam->input;
8744   vl_api_bier_table_add_del_t *mp;
8745   u8 is_add = 1;
8746   u32 set = 0, sub_domain = 0, hdr_len = 3;
8747   mpls_label_t local_label = MPLS_LABEL_INVALID;
8748   int ret;
8749
8750   /* Parse args required to build the message */
8751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8752     {
8753       if (unformat (i, "sub-domain %d", &sub_domain))
8754         ;
8755       else if (unformat (i, "set %d", &set))
8756         ;
8757       else if (unformat (i, "label %d", &local_label))
8758         ;
8759       else if (unformat (i, "hdr-len %d", &hdr_len))
8760         ;
8761       else if (unformat (i, "add"))
8762         is_add = 1;
8763       else if (unformat (i, "del"))
8764         is_add = 0;
8765       else
8766         {
8767           clib_warning ("parse error '%U'", format_unformat_error, i);
8768           return -99;
8769         }
8770     }
8771
8772   if (MPLS_LABEL_INVALID == local_label)
8773     {
8774       errmsg ("missing label\n");
8775       return -99;
8776     }
8777
8778   /* Construct the API message */
8779   M (BIER_TABLE_ADD_DEL, mp);
8780
8781   mp->bt_is_add = is_add;
8782   mp->bt_label = ntohl (local_label);
8783   mp->bt_tbl_id.bt_set = set;
8784   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8785   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8786
8787   /* send it... */
8788   S (mp);
8789
8790   /* Wait for a reply... */
8791   W (ret);
8792
8793   return (ret);
8794 }
8795
8796 static int
8797 api_bier_route_add_del (vat_main_t * vam)
8798 {
8799   unformat_input_t *i = vam->input;
8800   vl_api_bier_route_add_del_t *mp;
8801   u8 is_add = 1;
8802   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8803   ip4_address_t v4_next_hop_address;
8804   ip6_address_t v6_next_hop_address;
8805   u8 next_hop_set = 0;
8806   u8 next_hop_proto_is_ip4 = 1;
8807   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8808   int ret;
8809
8810   /* Parse args required to build the message */
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8814         {
8815           next_hop_proto_is_ip4 = 1;
8816           next_hop_set = 1;
8817         }
8818       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8819         {
8820           next_hop_proto_is_ip4 = 0;
8821           next_hop_set = 1;
8822         }
8823       if (unformat (i, "sub-domain %d", &sub_domain))
8824         ;
8825       else if (unformat (i, "set %d", &set))
8826         ;
8827       else if (unformat (i, "hdr-len %d", &hdr_len))
8828         ;
8829       else if (unformat (i, "bp %d", &bp))
8830         ;
8831       else if (unformat (i, "add"))
8832         is_add = 1;
8833       else if (unformat (i, "del"))
8834         is_add = 0;
8835       else if (unformat (i, "out-label %d", &next_hop_out_label))
8836         ;
8837       else
8838         {
8839           clib_warning ("parse error '%U'", format_unformat_error, i);
8840           return -99;
8841         }
8842     }
8843
8844   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8845     {
8846       errmsg ("next hop / label set\n");
8847       return -99;
8848     }
8849   if (0 == bp)
8850     {
8851       errmsg ("bit=position not set\n");
8852       return -99;
8853     }
8854
8855   /* Construct the API message */
8856   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8857
8858   mp->br_is_add = is_add;
8859   mp->br_route.br_tbl_id.bt_set = set;
8860   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8861   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8862   mp->br_route.br_bp = ntohs (bp);
8863   mp->br_route.br_n_paths = 1;
8864   mp->br_route.br_paths[0].n_labels = 1;
8865   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8866   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8867                                     FIB_API_PATH_NH_PROTO_IP4 :
8868                                     FIB_API_PATH_NH_PROTO_IP6);
8869
8870   if (next_hop_proto_is_ip4)
8871     {
8872       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8873                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8874     }
8875   else
8876     {
8877       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8878                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8879     }
8880
8881   /* send it... */
8882   S (mp);
8883
8884   /* Wait for a reply... */
8885   W (ret);
8886
8887   return (ret);
8888 }
8889
8890 static int
8891 api_proxy_arp_add_del (vat_main_t * vam)
8892 {
8893   unformat_input_t *i = vam->input;
8894   vl_api_proxy_arp_add_del_t *mp;
8895   u32 vrf_id = 0;
8896   u8 is_add = 1;
8897   vl_api_ip4_address_t lo, hi;
8898   u8 range_set = 0;
8899   int ret;
8900
8901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902     {
8903       if (unformat (i, "vrf %d", &vrf_id))
8904         ;
8905       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8906                          unformat_vl_api_ip4_address, &hi))
8907         range_set = 1;
8908       else if (unformat (i, "del"))
8909         is_add = 0;
8910       else
8911         {
8912           clib_warning ("parse error '%U'", format_unformat_error, i);
8913           return -99;
8914         }
8915     }
8916
8917   if (range_set == 0)
8918     {
8919       errmsg ("address range not set");
8920       return -99;
8921     }
8922
8923   M (PROXY_ARP_ADD_DEL, mp);
8924
8925   mp->proxy.table_id = ntohl (vrf_id);
8926   mp->is_add = is_add;
8927   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8928   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8929
8930   S (mp);
8931   W (ret);
8932   return ret;
8933 }
8934
8935 static int
8936 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8937 {
8938   unformat_input_t *i = vam->input;
8939   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8940   u32 sw_if_index;
8941   u8 enable = 1;
8942   u8 sw_if_index_set = 0;
8943   int ret;
8944
8945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8946     {
8947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8948         sw_if_index_set = 1;
8949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         sw_if_index_set = 1;
8951       else if (unformat (i, "enable"))
8952         enable = 1;
8953       else if (unformat (i, "disable"))
8954         enable = 0;
8955       else
8956         {
8957           clib_warning ("parse error '%U'", format_unformat_error, i);
8958           return -99;
8959         }
8960     }
8961
8962   if (sw_if_index_set == 0)
8963     {
8964       errmsg ("missing interface name or sw_if_index");
8965       return -99;
8966     }
8967
8968   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8969
8970   mp->sw_if_index = ntohl (sw_if_index);
8971   mp->enable_disable = enable;
8972
8973   S (mp);
8974   W (ret);
8975   return ret;
8976 }
8977
8978 static int
8979 api_mpls_tunnel_add_del (vat_main_t * vam)
8980 {
8981   unformat_input_t *i = vam->input;
8982   vl_api_mpls_tunnel_add_del_t *mp;
8983
8984   vl_api_fib_path_t paths[8];
8985   u32 sw_if_index = ~0;
8986   u8 path_count = 0;
8987   u8 l2_only = 0;
8988   u8 is_add = 1;
8989   int ret;
8990
8991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8992     {
8993       if (unformat (i, "add"))
8994         is_add = 1;
8995       else
8996         if (unformat
8997             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8998         is_add = 0;
8999       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9000         is_add = 0;
9001       else if (unformat (i, "l2-only"))
9002         l2_only = 1;
9003       else
9004         if (unformat
9005             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9006         {
9007           path_count++;
9008           if (8 == path_count)
9009             {
9010               errmsg ("max 8 paths");
9011               return -99;
9012             }
9013         }
9014       else
9015         {
9016           clib_warning ("parse error '%U'", format_unformat_error, i);
9017           return -99;
9018         }
9019     }
9020
9021   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9022
9023   mp->mt_is_add = is_add;
9024   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9025   mp->mt_tunnel.mt_l2_only = l2_only;
9026   mp->mt_tunnel.mt_is_multicast = 0;
9027   mp->mt_tunnel.mt_n_paths = path_count;
9028
9029   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9030                sizeof (paths[0]) * path_count);
9031
9032   S (mp);
9033   W (ret);
9034   return ret;
9035 }
9036
9037 static int
9038 api_sw_interface_set_unnumbered (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_sw_interface_set_unnumbered_t *mp;
9042   u32 sw_if_index;
9043   u32 unnum_sw_index = ~0;
9044   u8 is_add = 1;
9045   u8 sw_if_index_set = 0;
9046   int ret;
9047
9048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9049     {
9050       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9051         sw_if_index_set = 1;
9052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9053         sw_if_index_set = 1;
9054       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9055         ;
9056       else if (unformat (i, "del"))
9057         is_add = 0;
9058       else
9059         {
9060           clib_warning ("parse error '%U'", format_unformat_error, i);
9061           return -99;
9062         }
9063     }
9064
9065   if (sw_if_index_set == 0)
9066     {
9067       errmsg ("missing interface name or sw_if_index");
9068       return -99;
9069     }
9070
9071   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9072
9073   mp->sw_if_index = ntohl (sw_if_index);
9074   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9075   mp->is_add = is_add;
9076
9077   S (mp);
9078   W (ret);
9079   return ret;
9080 }
9081
9082 static int
9083 api_ip_neighbor_add_del (vat_main_t * vam)
9084 {
9085   vl_api_mac_address_t mac_address;
9086   unformat_input_t *i = vam->input;
9087   vl_api_ip_neighbor_add_del_t *mp;
9088   vl_api_address_t ip_address;
9089   u32 sw_if_index;
9090   u8 sw_if_index_set = 0;
9091   u8 is_add = 1;
9092   u8 mac_set = 0;
9093   u8 address_set = 0;
9094   int ret;
9095   ip_neighbor_flags_t flags;
9096
9097   flags = IP_NEIGHBOR_FLAG_NONE;
9098   clib_memset (&ip_address, 0, sizeof (ip_address));
9099   clib_memset (&mac_address, 0, sizeof (mac_address));
9100
9101   /* Parse args required to build the message */
9102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9105         {
9106           mac_set = 1;
9107         }
9108       else if (unformat (i, "del"))
9109         is_add = 0;
9110       else
9111         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9112         sw_if_index_set = 1;
9113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9114         sw_if_index_set = 1;
9115       else if (unformat (i, "static"))
9116         flags |= IP_NEIGHBOR_FLAG_STATIC;
9117       else if (unformat (i, "no-fib-entry"))
9118         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9119       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9120         address_set = 1;
9121       else
9122         {
9123           clib_warning ("parse error '%U'", format_unformat_error, i);
9124           return -99;
9125         }
9126     }
9127
9128   if (sw_if_index_set == 0)
9129     {
9130       errmsg ("missing interface name or sw_if_index");
9131       return -99;
9132     }
9133   if (!address_set)
9134     {
9135       errmsg ("no address set");
9136       return -99;
9137     }
9138
9139   /* Construct the API message */
9140   M (IP_NEIGHBOR_ADD_DEL, mp);
9141
9142   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9143   mp->is_add = is_add;
9144   mp->neighbor.flags = htonl (flags);
9145   if (mac_set)
9146     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9147                  sizeof (mac_address));
9148   if (address_set)
9149     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9150
9151   /* send it... */
9152   S (mp);
9153
9154   /* Wait for a reply, return good/bad news  */
9155   W (ret);
9156   return ret;
9157 }
9158
9159 static int
9160 api_create_vlan_subif (vat_main_t * vam)
9161 {
9162   unformat_input_t *i = vam->input;
9163   vl_api_create_vlan_subif_t *mp;
9164   u32 sw_if_index;
9165   u8 sw_if_index_set = 0;
9166   u32 vlan_id;
9167   u8 vlan_id_set = 0;
9168   int ret;
9169
9170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9171     {
9172       if (unformat (i, "sw_if_index %d", &sw_if_index))
9173         sw_if_index_set = 1;
9174       else
9175         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9176         sw_if_index_set = 1;
9177       else if (unformat (i, "vlan %d", &vlan_id))
9178         vlan_id_set = 1;
9179       else
9180         {
9181           clib_warning ("parse error '%U'", format_unformat_error, i);
9182           return -99;
9183         }
9184     }
9185
9186   if (sw_if_index_set == 0)
9187     {
9188       errmsg ("missing interface name or sw_if_index");
9189       return -99;
9190     }
9191
9192   if (vlan_id_set == 0)
9193     {
9194       errmsg ("missing vlan_id");
9195       return -99;
9196     }
9197   M (CREATE_VLAN_SUBIF, mp);
9198
9199   mp->sw_if_index = ntohl (sw_if_index);
9200   mp->vlan_id = ntohl (vlan_id);
9201
9202   S (mp);
9203   W (ret);
9204   return ret;
9205 }
9206
9207 #define foreach_create_subif_bit                \
9208 _(no_tags)                                      \
9209 _(one_tag)                                      \
9210 _(two_tags)                                     \
9211 _(dot1ad)                                       \
9212 _(exact_match)                                  \
9213 _(default_sub)                                  \
9214 _(outer_vlan_id_any)                            \
9215 _(inner_vlan_id_any)
9216
9217 static int
9218 api_create_subif (vat_main_t * vam)
9219 {
9220   unformat_input_t *i = vam->input;
9221   vl_api_create_subif_t *mp;
9222   u32 sw_if_index;
9223   u8 sw_if_index_set = 0;
9224   u32 sub_id;
9225   u8 sub_id_set = 0;
9226   u32 no_tags = 0;
9227   u32 one_tag = 0;
9228   u32 two_tags = 0;
9229   u32 dot1ad = 0;
9230   u32 exact_match = 0;
9231   u32 default_sub = 0;
9232   u32 outer_vlan_id_any = 0;
9233   u32 inner_vlan_id_any = 0;
9234   u32 tmp;
9235   u16 outer_vlan_id = 0;
9236   u16 inner_vlan_id = 0;
9237   int ret;
9238
9239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9240     {
9241       if (unformat (i, "sw_if_index %d", &sw_if_index))
9242         sw_if_index_set = 1;
9243       else
9244         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9245         sw_if_index_set = 1;
9246       else if (unformat (i, "sub_id %d", &sub_id))
9247         sub_id_set = 1;
9248       else if (unformat (i, "outer_vlan_id %d", &tmp))
9249         outer_vlan_id = tmp;
9250       else if (unformat (i, "inner_vlan_id %d", &tmp))
9251         inner_vlan_id = tmp;
9252
9253 #define _(a) else if (unformat (i, #a)) a = 1 ;
9254       foreach_create_subif_bit
9255 #undef _
9256         else
9257         {
9258           clib_warning ("parse error '%U'", format_unformat_error, i);
9259           return -99;
9260         }
9261     }
9262
9263   if (sw_if_index_set == 0)
9264     {
9265       errmsg ("missing interface name or sw_if_index");
9266       return -99;
9267     }
9268
9269   if (sub_id_set == 0)
9270     {
9271       errmsg ("missing sub_id");
9272       return -99;
9273     }
9274   M (CREATE_SUBIF, mp);
9275
9276   mp->sw_if_index = ntohl (sw_if_index);
9277   mp->sub_id = ntohl (sub_id);
9278
9279 #define _(a) mp->a = a;
9280   foreach_create_subif_bit;
9281 #undef _
9282
9283   mp->outer_vlan_id = ntohs (outer_vlan_id);
9284   mp->inner_vlan_id = ntohs (inner_vlan_id);
9285
9286   S (mp);
9287   W (ret);
9288   return ret;
9289 }
9290
9291 static int
9292 api_reset_fib (vat_main_t * vam)
9293 {
9294   unformat_input_t *i = vam->input;
9295   vl_api_reset_fib_t *mp;
9296   u32 vrf_id = 0;
9297   u8 is_ipv6 = 0;
9298   u8 vrf_id_set = 0;
9299
9300   int ret;
9301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9302     {
9303       if (unformat (i, "vrf %d", &vrf_id))
9304         vrf_id_set = 1;
9305       else if (unformat (i, "ipv6"))
9306         is_ipv6 = 1;
9307       else
9308         {
9309           clib_warning ("parse error '%U'", format_unformat_error, i);
9310           return -99;
9311         }
9312     }
9313
9314   if (vrf_id_set == 0)
9315     {
9316       errmsg ("missing vrf id");
9317       return -99;
9318     }
9319
9320   M (RESET_FIB, mp);
9321
9322   mp->vrf_id = ntohl (vrf_id);
9323   mp->is_ipv6 = is_ipv6;
9324
9325   S (mp);
9326   W (ret);
9327   return ret;
9328 }
9329
9330 static int
9331 api_dhcp_proxy_config (vat_main_t * vam)
9332 {
9333   unformat_input_t *i = vam->input;
9334   vl_api_dhcp_proxy_config_t *mp;
9335   u32 rx_vrf_id = 0;
9336   u32 server_vrf_id = 0;
9337   u8 is_add = 1;
9338   u8 v4_address_set = 0;
9339   u8 v6_address_set = 0;
9340   ip4_address_t v4address;
9341   ip6_address_t v6address;
9342   u8 v4_src_address_set = 0;
9343   u8 v6_src_address_set = 0;
9344   ip4_address_t v4srcaddress;
9345   ip6_address_t v6srcaddress;
9346   int ret;
9347
9348   /* Parse args required to build the message */
9349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9350     {
9351       if (unformat (i, "del"))
9352         is_add = 0;
9353       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9354         ;
9355       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9356         ;
9357       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9358         v4_address_set = 1;
9359       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9360         v6_address_set = 1;
9361       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9362         v4_src_address_set = 1;
9363       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9364         v6_src_address_set = 1;
9365       else
9366         break;
9367     }
9368
9369   if (v4_address_set && v6_address_set)
9370     {
9371       errmsg ("both v4 and v6 server addresses set");
9372       return -99;
9373     }
9374   if (!v4_address_set && !v6_address_set)
9375     {
9376       errmsg ("no server addresses set");
9377       return -99;
9378     }
9379
9380   if (v4_src_address_set && v6_src_address_set)
9381     {
9382       errmsg ("both v4 and v6  src addresses set");
9383       return -99;
9384     }
9385   if (!v4_src_address_set && !v6_src_address_set)
9386     {
9387       errmsg ("no src addresses set");
9388       return -99;
9389     }
9390
9391   if (!(v4_src_address_set && v4_address_set) &&
9392       !(v6_src_address_set && v6_address_set))
9393     {
9394       errmsg ("no matching server and src addresses set");
9395       return -99;
9396     }
9397
9398   /* Construct the API message */
9399   M (DHCP_PROXY_CONFIG, mp);
9400
9401   mp->is_add = is_add;
9402   mp->rx_vrf_id = ntohl (rx_vrf_id);
9403   mp->server_vrf_id = ntohl (server_vrf_id);
9404   if (v6_address_set)
9405     {
9406       mp->is_ipv6 = 1;
9407       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9408       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9409     }
9410   else
9411     {
9412       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9413       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9414     }
9415
9416   /* send it... */
9417   S (mp);
9418
9419   /* Wait for a reply, return good/bad news  */
9420   W (ret);
9421   return ret;
9422 }
9423
9424 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9425 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9426
9427 static void
9428 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9429 {
9430   vat_main_t *vam = &vat_main;
9431   u32 i, count = mp->count;
9432   vl_api_dhcp_server_t *s;
9433
9434   if (mp->is_ipv6)
9435     print (vam->ofp,
9436            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9437            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9438            ntohl (mp->rx_vrf_id),
9439            format_ip6_address, mp->dhcp_src_address,
9440            mp->vss_type, mp->vss_vpn_ascii_id,
9441            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9442   else
9443     print (vam->ofp,
9444            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9445            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9446            ntohl (mp->rx_vrf_id),
9447            format_ip4_address, mp->dhcp_src_address,
9448            mp->vss_type, mp->vss_vpn_ascii_id,
9449            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9450
9451   for (i = 0; i < count; i++)
9452     {
9453       s = &mp->servers[i];
9454
9455       if (mp->is_ipv6)
9456         print (vam->ofp,
9457                " Server Table-ID %d, Server Address %U",
9458                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9459       else
9460         print (vam->ofp,
9461                " Server Table-ID %d, Server Address %U",
9462                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9463     }
9464 }
9465
9466 static void vl_api_dhcp_proxy_details_t_handler_json
9467   (vl_api_dhcp_proxy_details_t * mp)
9468 {
9469   vat_main_t *vam = &vat_main;
9470   vat_json_node_t *node = NULL;
9471   u32 i, count = mp->count;
9472   struct in_addr ip4;
9473   struct in6_addr ip6;
9474   vl_api_dhcp_server_t *s;
9475
9476   if (VAT_JSON_ARRAY != vam->json_tree.type)
9477     {
9478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9479       vat_json_init_array (&vam->json_tree);
9480     }
9481   node = vat_json_array_add (&vam->json_tree);
9482
9483   vat_json_init_object (node);
9484   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9485   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9486                              sizeof (mp->vss_type));
9487   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9488                                    mp->vss_vpn_ascii_id);
9489   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9490   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9491
9492   if (mp->is_ipv6)
9493     {
9494       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9495       vat_json_object_add_ip6 (node, "src_address", ip6);
9496     }
9497   else
9498     {
9499       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9500       vat_json_object_add_ip4 (node, "src_address", ip4);
9501     }
9502
9503   for (i = 0; i < count; i++)
9504     {
9505       s = &mp->servers[i];
9506
9507       vat_json_object_add_uint (node, "server-table-id",
9508                                 ntohl (s->server_vrf_id));
9509
9510       if (mp->is_ipv6)
9511         {
9512           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9513           vat_json_object_add_ip4 (node, "src_address", ip4);
9514         }
9515       else
9516         {
9517           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9518           vat_json_object_add_ip6 (node, "server_address", ip6);
9519         }
9520     }
9521 }
9522
9523 static int
9524 api_dhcp_proxy_dump (vat_main_t * vam)
9525 {
9526   unformat_input_t *i = vam->input;
9527   vl_api_control_ping_t *mp_ping;
9528   vl_api_dhcp_proxy_dump_t *mp;
9529   u8 is_ipv6 = 0;
9530   int ret;
9531
9532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9533     {
9534       if (unformat (i, "ipv6"))
9535         is_ipv6 = 1;
9536       else
9537         {
9538           clib_warning ("parse error '%U'", format_unformat_error, i);
9539           return -99;
9540         }
9541     }
9542
9543   M (DHCP_PROXY_DUMP, mp);
9544
9545   mp->is_ip6 = is_ipv6;
9546   S (mp);
9547
9548   /* Use a control ping for synchronization */
9549   MPING (CONTROL_PING, mp_ping);
9550   S (mp_ping);
9551
9552   W (ret);
9553   return ret;
9554 }
9555
9556 static int
9557 api_dhcp_proxy_set_vss (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_dhcp_proxy_set_vss_t *mp;
9561   u8 is_ipv6 = 0;
9562   u8 is_add = 1;
9563   u32 tbl_id = ~0;
9564   u8 vss_type = VSS_TYPE_DEFAULT;
9565   u8 *vpn_ascii_id = 0;
9566   u32 oui = 0;
9567   u32 fib_id = 0;
9568   int ret;
9569
9570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9571     {
9572       if (unformat (i, "tbl_id %d", &tbl_id))
9573         ;
9574       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9575         vss_type = VSS_TYPE_ASCII;
9576       else if (unformat (i, "fib_id %d", &fib_id))
9577         vss_type = VSS_TYPE_VPN_ID;
9578       else if (unformat (i, "oui %d", &oui))
9579         vss_type = VSS_TYPE_VPN_ID;
9580       else if (unformat (i, "ipv6"))
9581         is_ipv6 = 1;
9582       else if (unformat (i, "del"))
9583         is_add = 0;
9584       else
9585         break;
9586     }
9587
9588   if (tbl_id == ~0)
9589     {
9590       errmsg ("missing tbl_id ");
9591       vec_free (vpn_ascii_id);
9592       return -99;
9593     }
9594
9595   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9596     {
9597       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9598       vec_free (vpn_ascii_id);
9599       return -99;
9600     }
9601
9602   M (DHCP_PROXY_SET_VSS, mp);
9603   mp->tbl_id = ntohl (tbl_id);
9604   mp->vss_type = vss_type;
9605   if (vpn_ascii_id)
9606     {
9607       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9608       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9609     }
9610   mp->vpn_index = ntohl (fib_id);
9611   mp->oui = ntohl (oui);
9612   mp->is_ipv6 = is_ipv6;
9613   mp->is_add = is_add;
9614
9615   S (mp);
9616   W (ret);
9617
9618   vec_free (vpn_ascii_id);
9619   return ret;
9620 }
9621
9622 static int
9623 api_dhcp_client_config (vat_main_t * vam)
9624 {
9625   unformat_input_t *i = vam->input;
9626   vl_api_dhcp_client_config_t *mp;
9627   u32 sw_if_index;
9628   u8 sw_if_index_set = 0;
9629   u8 is_add = 1;
9630   u8 *hostname = 0;
9631   u8 disable_event = 0;
9632   int ret;
9633
9634   /* Parse args required to build the message */
9635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9636     {
9637       if (unformat (i, "del"))
9638         is_add = 0;
9639       else
9640         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9641         sw_if_index_set = 1;
9642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9643         sw_if_index_set = 1;
9644       else if (unformat (i, "hostname %s", &hostname))
9645         ;
9646       else if (unformat (i, "disable_event"))
9647         disable_event = 1;
9648       else
9649         break;
9650     }
9651
9652   if (sw_if_index_set == 0)
9653     {
9654       errmsg ("missing interface name or sw_if_index");
9655       return -99;
9656     }
9657
9658   if (vec_len (hostname) > 63)
9659     {
9660       errmsg ("hostname too long");
9661     }
9662   vec_add1 (hostname, 0);
9663
9664   /* Construct the API message */
9665   M (DHCP_CLIENT_CONFIG, mp);
9666
9667   mp->is_add = is_add;
9668   mp->client.sw_if_index = htonl (sw_if_index);
9669   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9670   vec_free (hostname);
9671   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9672   mp->client.pid = htonl (getpid ());
9673
9674   /* send it... */
9675   S (mp);
9676
9677   /* Wait for a reply, return good/bad news  */
9678   W (ret);
9679   return ret;
9680 }
9681
9682 static int
9683 api_set_ip_flow_hash (vat_main_t * vam)
9684 {
9685   unformat_input_t *i = vam->input;
9686   vl_api_set_ip_flow_hash_t *mp;
9687   u32 vrf_id = 0;
9688   u8 is_ipv6 = 0;
9689   u8 vrf_id_set = 0;
9690   u8 src = 0;
9691   u8 dst = 0;
9692   u8 sport = 0;
9693   u8 dport = 0;
9694   u8 proto = 0;
9695   u8 reverse = 0;
9696   int ret;
9697
9698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9699     {
9700       if (unformat (i, "vrf %d", &vrf_id))
9701         vrf_id_set = 1;
9702       else if (unformat (i, "ipv6"))
9703         is_ipv6 = 1;
9704       else if (unformat (i, "src"))
9705         src = 1;
9706       else if (unformat (i, "dst"))
9707         dst = 1;
9708       else if (unformat (i, "sport"))
9709         sport = 1;
9710       else if (unformat (i, "dport"))
9711         dport = 1;
9712       else if (unformat (i, "proto"))
9713         proto = 1;
9714       else if (unformat (i, "reverse"))
9715         reverse = 1;
9716
9717       else
9718         {
9719           clib_warning ("parse error '%U'", format_unformat_error, i);
9720           return -99;
9721         }
9722     }
9723
9724   if (vrf_id_set == 0)
9725     {
9726       errmsg ("missing vrf id");
9727       return -99;
9728     }
9729
9730   M (SET_IP_FLOW_HASH, mp);
9731   mp->src = src;
9732   mp->dst = dst;
9733   mp->sport = sport;
9734   mp->dport = dport;
9735   mp->proto = proto;
9736   mp->reverse = reverse;
9737   mp->vrf_id = ntohl (vrf_id);
9738   mp->is_ipv6 = is_ipv6;
9739
9740   S (mp);
9741   W (ret);
9742   return ret;
9743 }
9744
9745 static int
9746 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   vl_api_sw_interface_ip6_enable_disable_t *mp;
9750   u32 sw_if_index;
9751   u8 sw_if_index_set = 0;
9752   u8 enable = 0;
9753   int ret;
9754
9755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9756     {
9757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9758         sw_if_index_set = 1;
9759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9760         sw_if_index_set = 1;
9761       else if (unformat (i, "enable"))
9762         enable = 1;
9763       else if (unformat (i, "disable"))
9764         enable = 0;
9765       else
9766         {
9767           clib_warning ("parse error '%U'", format_unformat_error, i);
9768           return -99;
9769         }
9770     }
9771
9772   if (sw_if_index_set == 0)
9773     {
9774       errmsg ("missing interface name or sw_if_index");
9775       return -99;
9776     }
9777
9778   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9779
9780   mp->sw_if_index = ntohl (sw_if_index);
9781   mp->enable = enable;
9782
9783   S (mp);
9784   W (ret);
9785   return ret;
9786 }
9787
9788 static int
9789 api_ip6nd_proxy_add_del (vat_main_t * vam)
9790 {
9791   unformat_input_t *i = vam->input;
9792   vl_api_ip6nd_proxy_add_del_t *mp;
9793   u32 sw_if_index = ~0;
9794   u8 v6_address_set = 0;
9795   vl_api_ip6_address_t v6address;
9796   u8 is_del = 0;
9797   int ret;
9798
9799   /* Parse args required to build the message */
9800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9801     {
9802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9803         ;
9804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9805         ;
9806       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9807         v6_address_set = 1;
9808       if (unformat (i, "del"))
9809         is_del = 1;
9810       else
9811         {
9812           clib_warning ("parse error '%U'", format_unformat_error, i);
9813           return -99;
9814         }
9815     }
9816
9817   if (sw_if_index == ~0)
9818     {
9819       errmsg ("missing interface name or sw_if_index");
9820       return -99;
9821     }
9822   if (!v6_address_set)
9823     {
9824       errmsg ("no address set");
9825       return -99;
9826     }
9827
9828   /* Construct the API message */
9829   M (IP6ND_PROXY_ADD_DEL, mp);
9830
9831   mp->is_del = is_del;
9832   mp->sw_if_index = ntohl (sw_if_index);
9833   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9834
9835   /* send it... */
9836   S (mp);
9837
9838   /* Wait for a reply, return good/bad news  */
9839   W (ret);
9840   return ret;
9841 }
9842
9843 static int
9844 api_ip6nd_proxy_dump (vat_main_t * vam)
9845 {
9846   vl_api_ip6nd_proxy_dump_t *mp;
9847   vl_api_control_ping_t *mp_ping;
9848   int ret;
9849
9850   M (IP6ND_PROXY_DUMP, mp);
9851
9852   S (mp);
9853
9854   /* Use a control ping for synchronization */
9855   MPING (CONTROL_PING, mp_ping);
9856   S (mp_ping);
9857
9858   W (ret);
9859   return ret;
9860 }
9861
9862 static void vl_api_ip6nd_proxy_details_t_handler
9863   (vl_api_ip6nd_proxy_details_t * mp)
9864 {
9865   vat_main_t *vam = &vat_main;
9866
9867   print (vam->ofp, "host %U sw_if_index %d",
9868          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9869 }
9870
9871 static void vl_api_ip6nd_proxy_details_t_handler_json
9872   (vl_api_ip6nd_proxy_details_t * mp)
9873 {
9874   vat_main_t *vam = &vat_main;
9875   struct in6_addr ip6;
9876   vat_json_node_t *node = NULL;
9877
9878   if (VAT_JSON_ARRAY != vam->json_tree.type)
9879     {
9880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9881       vat_json_init_array (&vam->json_tree);
9882     }
9883   node = vat_json_array_add (&vam->json_tree);
9884
9885   vat_json_init_object (node);
9886   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9887
9888   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9889   vat_json_object_add_ip6 (node, "host", ip6);
9890 }
9891
9892 static int
9893 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9894 {
9895   unformat_input_t *i = vam->input;
9896   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9897   u32 sw_if_index;
9898   u8 sw_if_index_set = 0;
9899   u8 v6_address_set = 0;
9900   vl_api_prefix_t pfx;
9901   u8 use_default = 0;
9902   u8 no_advertise = 0;
9903   u8 off_link = 0;
9904   u8 no_autoconfig = 0;
9905   u8 no_onlink = 0;
9906   u8 is_no = 0;
9907   u32 val_lifetime = 0;
9908   u32 pref_lifetime = 0;
9909   int ret;
9910
9911   /* Parse args required to build the message */
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9919         v6_address_set = 1;
9920       else if (unformat (i, "val_life %d", &val_lifetime))
9921         ;
9922       else if (unformat (i, "pref_life %d", &pref_lifetime))
9923         ;
9924       else if (unformat (i, "def"))
9925         use_default = 1;
9926       else if (unformat (i, "noadv"))
9927         no_advertise = 1;
9928       else if (unformat (i, "offl"))
9929         off_link = 1;
9930       else if (unformat (i, "noauto"))
9931         no_autoconfig = 1;
9932       else if (unformat (i, "nolink"))
9933         no_onlink = 1;
9934       else if (unformat (i, "isno"))
9935         is_no = 1;
9936       else
9937         {
9938           clib_warning ("parse error '%U'", format_unformat_error, i);
9939           return -99;
9940         }
9941     }
9942
9943   if (sw_if_index_set == 0)
9944     {
9945       errmsg ("missing interface name or sw_if_index");
9946       return -99;
9947     }
9948   if (!v6_address_set)
9949     {
9950       errmsg ("no address set");
9951       return -99;
9952     }
9953
9954   /* Construct the API message */
9955   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9956
9957   mp->sw_if_index = ntohl (sw_if_index);
9958   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9959   mp->use_default = use_default;
9960   mp->no_advertise = no_advertise;
9961   mp->off_link = off_link;
9962   mp->no_autoconfig = no_autoconfig;
9963   mp->no_onlink = no_onlink;
9964   mp->is_no = is_no;
9965   mp->val_lifetime = ntohl (val_lifetime);
9966   mp->pref_lifetime = ntohl (pref_lifetime);
9967
9968   /* send it... */
9969   S (mp);
9970
9971   /* Wait for a reply, return good/bad news  */
9972   W (ret);
9973   return ret;
9974 }
9975
9976 static int
9977 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9978 {
9979   unformat_input_t *i = vam->input;
9980   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9981   u32 sw_if_index;
9982   u8 sw_if_index_set = 0;
9983   u8 suppress = 0;
9984   u8 managed = 0;
9985   u8 other = 0;
9986   u8 ll_option = 0;
9987   u8 send_unicast = 0;
9988   u8 cease = 0;
9989   u8 is_no = 0;
9990   u8 default_router = 0;
9991   u32 max_interval = 0;
9992   u32 min_interval = 0;
9993   u32 lifetime = 0;
9994   u32 initial_count = 0;
9995   u32 initial_interval = 0;
9996   int ret;
9997
9998
9999   /* Parse args required to build the message */
10000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10001     {
10002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10003         sw_if_index_set = 1;
10004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10005         sw_if_index_set = 1;
10006       else if (unformat (i, "maxint %d", &max_interval))
10007         ;
10008       else if (unformat (i, "minint %d", &min_interval))
10009         ;
10010       else if (unformat (i, "life %d", &lifetime))
10011         ;
10012       else if (unformat (i, "count %d", &initial_count))
10013         ;
10014       else if (unformat (i, "interval %d", &initial_interval))
10015         ;
10016       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10017         suppress = 1;
10018       else if (unformat (i, "managed"))
10019         managed = 1;
10020       else if (unformat (i, "other"))
10021         other = 1;
10022       else if (unformat (i, "ll"))
10023         ll_option = 1;
10024       else if (unformat (i, "send"))
10025         send_unicast = 1;
10026       else if (unformat (i, "cease"))
10027         cease = 1;
10028       else if (unformat (i, "isno"))
10029         is_no = 1;
10030       else if (unformat (i, "def"))
10031         default_router = 1;
10032       else
10033         {
10034           clib_warning ("parse error '%U'", format_unformat_error, i);
10035           return -99;
10036         }
10037     }
10038
10039   if (sw_if_index_set == 0)
10040     {
10041       errmsg ("missing interface name or sw_if_index");
10042       return -99;
10043     }
10044
10045   /* Construct the API message */
10046   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10047
10048   mp->sw_if_index = ntohl (sw_if_index);
10049   mp->max_interval = ntohl (max_interval);
10050   mp->min_interval = ntohl (min_interval);
10051   mp->lifetime = ntohl (lifetime);
10052   mp->initial_count = ntohl (initial_count);
10053   mp->initial_interval = ntohl (initial_interval);
10054   mp->suppress = suppress;
10055   mp->managed = managed;
10056   mp->other = other;
10057   mp->ll_option = ll_option;
10058   mp->send_unicast = send_unicast;
10059   mp->cease = cease;
10060   mp->is_no = is_no;
10061   mp->default_router = default_router;
10062
10063   /* send it... */
10064   S (mp);
10065
10066   /* Wait for a reply, return good/bad news  */
10067   W (ret);
10068   return ret;
10069 }
10070
10071 static int
10072 api_set_arp_neighbor_limit (vat_main_t * vam)
10073 {
10074   unformat_input_t *i = vam->input;
10075   vl_api_set_arp_neighbor_limit_t *mp;
10076   u32 arp_nbr_limit;
10077   u8 limit_set = 0;
10078   u8 is_ipv6 = 0;
10079   int ret;
10080
10081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10082     {
10083       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10084         limit_set = 1;
10085       else if (unformat (i, "ipv6"))
10086         is_ipv6 = 1;
10087       else
10088         {
10089           clib_warning ("parse error '%U'", format_unformat_error, i);
10090           return -99;
10091         }
10092     }
10093
10094   if (limit_set == 0)
10095     {
10096       errmsg ("missing limit value");
10097       return -99;
10098     }
10099
10100   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10101
10102   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10103   mp->is_ipv6 = is_ipv6;
10104
10105   S (mp);
10106   W (ret);
10107   return ret;
10108 }
10109
10110 static int
10111 api_l2_patch_add_del (vat_main_t * vam)
10112 {
10113   unformat_input_t *i = vam->input;
10114   vl_api_l2_patch_add_del_t *mp;
10115   u32 rx_sw_if_index;
10116   u8 rx_sw_if_index_set = 0;
10117   u32 tx_sw_if_index;
10118   u8 tx_sw_if_index_set = 0;
10119   u8 is_add = 1;
10120   int ret;
10121
10122   /* Parse args required to build the message */
10123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10124     {
10125       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10126         rx_sw_if_index_set = 1;
10127       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10128         tx_sw_if_index_set = 1;
10129       else if (unformat (i, "rx"))
10130         {
10131           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10132             {
10133               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10134                             &rx_sw_if_index))
10135                 rx_sw_if_index_set = 1;
10136             }
10137           else
10138             break;
10139         }
10140       else if (unformat (i, "tx"))
10141         {
10142           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10143             {
10144               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10145                             &tx_sw_if_index))
10146                 tx_sw_if_index_set = 1;
10147             }
10148           else
10149             break;
10150         }
10151       else if (unformat (i, "del"))
10152         is_add = 0;
10153       else
10154         break;
10155     }
10156
10157   if (rx_sw_if_index_set == 0)
10158     {
10159       errmsg ("missing rx interface name or rx_sw_if_index");
10160       return -99;
10161     }
10162
10163   if (tx_sw_if_index_set == 0)
10164     {
10165       errmsg ("missing tx interface name or tx_sw_if_index");
10166       return -99;
10167     }
10168
10169   M (L2_PATCH_ADD_DEL, mp);
10170
10171   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10172   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10173   mp->is_add = is_add;
10174
10175   S (mp);
10176   W (ret);
10177   return ret;
10178 }
10179
10180 u8 is_del;
10181 u8 localsid_addr[16];
10182 u8 end_psp;
10183 u8 behavior;
10184 u32 sw_if_index;
10185 u32 vlan_index;
10186 u32 fib_table;
10187 u8 nh_addr[16];
10188
10189 static int
10190 api_sr_localsid_add_del (vat_main_t * vam)
10191 {
10192   unformat_input_t *i = vam->input;
10193   vl_api_sr_localsid_add_del_t *mp;
10194
10195   u8 is_del;
10196   ip6_address_t localsid;
10197   u8 end_psp = 0;
10198   u8 behavior = ~0;
10199   u32 sw_if_index;
10200   u32 fib_table = ~(u32) 0;
10201   ip6_address_t nh_addr6;
10202   ip4_address_t nh_addr4;
10203   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10204   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10205
10206   bool nexthop_set = 0;
10207
10208   int ret;
10209
10210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10211     {
10212       if (unformat (i, "del"))
10213         is_del = 1;
10214       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10215       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10216         nexthop_set = 1;
10217       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10218         nexthop_set = 1;
10219       else if (unformat (i, "behavior %u", &behavior));
10220       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10221       else if (unformat (i, "fib-table %u", &fib_table));
10222       else if (unformat (i, "end.psp %u", &behavior));
10223       else
10224         break;
10225     }
10226
10227   M (SR_LOCALSID_ADD_DEL, mp);
10228
10229   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10230   if (nexthop_set)
10231     {
10232       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10233       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10234     }
10235   mp->behavior = behavior;
10236   mp->sw_if_index = ntohl (sw_if_index);
10237   mp->fib_table = ntohl (fib_table);
10238   mp->end_psp = end_psp;
10239   mp->is_del = is_del;
10240
10241   S (mp);
10242   W (ret);
10243   return ret;
10244 }
10245
10246 static int
10247 api_ioam_enable (vat_main_t * vam)
10248 {
10249   unformat_input_t *input = vam->input;
10250   vl_api_ioam_enable_t *mp;
10251   u32 id = 0;
10252   int has_trace_option = 0;
10253   int has_pot_option = 0;
10254   int has_seqno_option = 0;
10255   int has_analyse_option = 0;
10256   int ret;
10257
10258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10259     {
10260       if (unformat (input, "trace"))
10261         has_trace_option = 1;
10262       else if (unformat (input, "pot"))
10263         has_pot_option = 1;
10264       else if (unformat (input, "seqno"))
10265         has_seqno_option = 1;
10266       else if (unformat (input, "analyse"))
10267         has_analyse_option = 1;
10268       else
10269         break;
10270     }
10271   M (IOAM_ENABLE, mp);
10272   mp->id = htons (id);
10273   mp->seqno = has_seqno_option;
10274   mp->analyse = has_analyse_option;
10275   mp->pot_enable = has_pot_option;
10276   mp->trace_enable = has_trace_option;
10277
10278   S (mp);
10279   W (ret);
10280   return ret;
10281 }
10282
10283
10284 static int
10285 api_ioam_disable (vat_main_t * vam)
10286 {
10287   vl_api_ioam_disable_t *mp;
10288   int ret;
10289
10290   M (IOAM_DISABLE, mp);
10291   S (mp);
10292   W (ret);
10293   return ret;
10294 }
10295
10296 #define foreach_tcp_proto_field                 \
10297 _(src_port)                                     \
10298 _(dst_port)
10299
10300 #define foreach_udp_proto_field                 \
10301 _(src_port)                                     \
10302 _(dst_port)
10303
10304 #define foreach_ip4_proto_field                 \
10305 _(src_address)                                  \
10306 _(dst_address)                                  \
10307 _(tos)                                          \
10308 _(length)                                       \
10309 _(fragment_id)                                  \
10310 _(ttl)                                          \
10311 _(protocol)                                     \
10312 _(checksum)
10313
10314 typedef struct
10315 {
10316   u16 src_port, dst_port;
10317 } tcpudp_header_t;
10318
10319 #if VPP_API_TEST_BUILTIN == 0
10320 uword
10321 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10322 {
10323   u8 **maskp = va_arg (*args, u8 **);
10324   u8 *mask = 0;
10325   u8 found_something = 0;
10326   tcp_header_t *tcp;
10327
10328 #define _(a) u8 a=0;
10329   foreach_tcp_proto_field;
10330 #undef _
10331
10332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10333     {
10334       if (0);
10335 #define _(a) else if (unformat (input, #a)) a=1;
10336       foreach_tcp_proto_field
10337 #undef _
10338         else
10339         break;
10340     }
10341
10342 #define _(a) found_something += a;
10343   foreach_tcp_proto_field;
10344 #undef _
10345
10346   if (found_something == 0)
10347     return 0;
10348
10349   vec_validate (mask, sizeof (*tcp) - 1);
10350
10351   tcp = (tcp_header_t *) mask;
10352
10353 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10354   foreach_tcp_proto_field;
10355 #undef _
10356
10357   *maskp = mask;
10358   return 1;
10359 }
10360
10361 uword
10362 unformat_udp_mask (unformat_input_t * input, va_list * args)
10363 {
10364   u8 **maskp = va_arg (*args, u8 **);
10365   u8 *mask = 0;
10366   u8 found_something = 0;
10367   udp_header_t *udp;
10368
10369 #define _(a) u8 a=0;
10370   foreach_udp_proto_field;
10371 #undef _
10372
10373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (0);
10376 #define _(a) else if (unformat (input, #a)) a=1;
10377       foreach_udp_proto_field
10378 #undef _
10379         else
10380         break;
10381     }
10382
10383 #define _(a) found_something += a;
10384   foreach_udp_proto_field;
10385 #undef _
10386
10387   if (found_something == 0)
10388     return 0;
10389
10390   vec_validate (mask, sizeof (*udp) - 1);
10391
10392   udp = (udp_header_t *) mask;
10393
10394 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10395   foreach_udp_proto_field;
10396 #undef _
10397
10398   *maskp = mask;
10399   return 1;
10400 }
10401
10402 uword
10403 unformat_l4_mask (unformat_input_t * input, va_list * args)
10404 {
10405   u8 **maskp = va_arg (*args, u8 **);
10406   u16 src_port = 0, dst_port = 0;
10407   tcpudp_header_t *tcpudp;
10408
10409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10410     {
10411       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10412         return 1;
10413       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10414         return 1;
10415       else if (unformat (input, "src_port"))
10416         src_port = 0xFFFF;
10417       else if (unformat (input, "dst_port"))
10418         dst_port = 0xFFFF;
10419       else
10420         return 0;
10421     }
10422
10423   if (!src_port && !dst_port)
10424     return 0;
10425
10426   u8 *mask = 0;
10427   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10428
10429   tcpudp = (tcpudp_header_t *) mask;
10430   tcpudp->src_port = src_port;
10431   tcpudp->dst_port = dst_port;
10432
10433   *maskp = mask;
10434
10435   return 1;
10436 }
10437
10438 uword
10439 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10440 {
10441   u8 **maskp = va_arg (*args, u8 **);
10442   u8 *mask = 0;
10443   u8 found_something = 0;
10444   ip4_header_t *ip;
10445
10446 #define _(a) u8 a=0;
10447   foreach_ip4_proto_field;
10448 #undef _
10449   u8 version = 0;
10450   u8 hdr_length = 0;
10451
10452
10453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10454     {
10455       if (unformat (input, "version"))
10456         version = 1;
10457       else if (unformat (input, "hdr_length"))
10458         hdr_length = 1;
10459       else if (unformat (input, "src"))
10460         src_address = 1;
10461       else if (unformat (input, "dst"))
10462         dst_address = 1;
10463       else if (unformat (input, "proto"))
10464         protocol = 1;
10465
10466 #define _(a) else if (unformat (input, #a)) a=1;
10467       foreach_ip4_proto_field
10468 #undef _
10469         else
10470         break;
10471     }
10472
10473 #define _(a) found_something += a;
10474   foreach_ip4_proto_field;
10475 #undef _
10476
10477   if (found_something == 0)
10478     return 0;
10479
10480   vec_validate (mask, sizeof (*ip) - 1);
10481
10482   ip = (ip4_header_t *) mask;
10483
10484 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10485   foreach_ip4_proto_field;
10486 #undef _
10487
10488   ip->ip_version_and_header_length = 0;
10489
10490   if (version)
10491     ip->ip_version_and_header_length |= 0xF0;
10492
10493   if (hdr_length)
10494     ip->ip_version_and_header_length |= 0x0F;
10495
10496   *maskp = mask;
10497   return 1;
10498 }
10499
10500 #define foreach_ip6_proto_field                 \
10501 _(src_address)                                  \
10502 _(dst_address)                                  \
10503 _(payload_length)                               \
10504 _(hop_limit)                                    \
10505 _(protocol)
10506
10507 uword
10508 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10509 {
10510   u8 **maskp = va_arg (*args, u8 **);
10511   u8 *mask = 0;
10512   u8 found_something = 0;
10513   ip6_header_t *ip;
10514   u32 ip_version_traffic_class_and_flow_label;
10515
10516 #define _(a) u8 a=0;
10517   foreach_ip6_proto_field;
10518 #undef _
10519   u8 version = 0;
10520   u8 traffic_class = 0;
10521   u8 flow_label = 0;
10522
10523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10524     {
10525       if (unformat (input, "version"))
10526         version = 1;
10527       else if (unformat (input, "traffic-class"))
10528         traffic_class = 1;
10529       else if (unformat (input, "flow-label"))
10530         flow_label = 1;
10531       else if (unformat (input, "src"))
10532         src_address = 1;
10533       else if (unformat (input, "dst"))
10534         dst_address = 1;
10535       else if (unformat (input, "proto"))
10536         protocol = 1;
10537
10538 #define _(a) else if (unformat (input, #a)) a=1;
10539       foreach_ip6_proto_field
10540 #undef _
10541         else
10542         break;
10543     }
10544
10545 #define _(a) found_something += a;
10546   foreach_ip6_proto_field;
10547 #undef _
10548
10549   if (found_something == 0)
10550     return 0;
10551
10552   vec_validate (mask, sizeof (*ip) - 1);
10553
10554   ip = (ip6_header_t *) mask;
10555
10556 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10557   foreach_ip6_proto_field;
10558 #undef _
10559
10560   ip_version_traffic_class_and_flow_label = 0;
10561
10562   if (version)
10563     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10564
10565   if (traffic_class)
10566     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10567
10568   if (flow_label)
10569     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10570
10571   ip->ip_version_traffic_class_and_flow_label =
10572     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10573
10574   *maskp = mask;
10575   return 1;
10576 }
10577
10578 uword
10579 unformat_l3_mask (unformat_input_t * input, va_list * args)
10580 {
10581   u8 **maskp = va_arg (*args, u8 **);
10582
10583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10584     {
10585       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10586         return 1;
10587       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10588         return 1;
10589       else
10590         break;
10591     }
10592   return 0;
10593 }
10594
10595 uword
10596 unformat_l2_mask (unformat_input_t * input, va_list * args)
10597 {
10598   u8 **maskp = va_arg (*args, u8 **);
10599   u8 *mask = 0;
10600   u8 src = 0;
10601   u8 dst = 0;
10602   u8 proto = 0;
10603   u8 tag1 = 0;
10604   u8 tag2 = 0;
10605   u8 ignore_tag1 = 0;
10606   u8 ignore_tag2 = 0;
10607   u8 cos1 = 0;
10608   u8 cos2 = 0;
10609   u8 dot1q = 0;
10610   u8 dot1ad = 0;
10611   int len = 14;
10612
10613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10614     {
10615       if (unformat (input, "src"))
10616         src = 1;
10617       else if (unformat (input, "dst"))
10618         dst = 1;
10619       else if (unformat (input, "proto"))
10620         proto = 1;
10621       else if (unformat (input, "tag1"))
10622         tag1 = 1;
10623       else if (unformat (input, "tag2"))
10624         tag2 = 1;
10625       else if (unformat (input, "ignore-tag1"))
10626         ignore_tag1 = 1;
10627       else if (unformat (input, "ignore-tag2"))
10628         ignore_tag2 = 1;
10629       else if (unformat (input, "cos1"))
10630         cos1 = 1;
10631       else if (unformat (input, "cos2"))
10632         cos2 = 1;
10633       else if (unformat (input, "dot1q"))
10634         dot1q = 1;
10635       else if (unformat (input, "dot1ad"))
10636         dot1ad = 1;
10637       else
10638         break;
10639     }
10640   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10641        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10642     return 0;
10643
10644   if (tag1 || ignore_tag1 || cos1 || dot1q)
10645     len = 18;
10646   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10647     len = 22;
10648
10649   vec_validate (mask, len - 1);
10650
10651   if (dst)
10652     clib_memset (mask, 0xff, 6);
10653
10654   if (src)
10655     clib_memset (mask + 6, 0xff, 6);
10656
10657   if (tag2 || dot1ad)
10658     {
10659       /* inner vlan tag */
10660       if (tag2)
10661         {
10662           mask[19] = 0xff;
10663           mask[18] = 0x0f;
10664         }
10665       if (cos2)
10666         mask[18] |= 0xe0;
10667       if (proto)
10668         mask[21] = mask[20] = 0xff;
10669       if (tag1)
10670         {
10671           mask[15] = 0xff;
10672           mask[14] = 0x0f;
10673         }
10674       if (cos1)
10675         mask[14] |= 0xe0;
10676       *maskp = mask;
10677       return 1;
10678     }
10679   if (tag1 | dot1q)
10680     {
10681       if (tag1)
10682         {
10683           mask[15] = 0xff;
10684           mask[14] = 0x0f;
10685         }
10686       if (cos1)
10687         mask[14] |= 0xe0;
10688       if (proto)
10689         mask[16] = mask[17] = 0xff;
10690
10691       *maskp = mask;
10692       return 1;
10693     }
10694   if (cos2)
10695     mask[18] |= 0xe0;
10696   if (cos1)
10697     mask[14] |= 0xe0;
10698   if (proto)
10699     mask[12] = mask[13] = 0xff;
10700
10701   *maskp = mask;
10702   return 1;
10703 }
10704
10705 uword
10706 unformat_classify_mask (unformat_input_t * input, va_list * args)
10707 {
10708   u8 **maskp = va_arg (*args, u8 **);
10709   u32 *skipp = va_arg (*args, u32 *);
10710   u32 *matchp = va_arg (*args, u32 *);
10711   u32 match;
10712   u8 *mask = 0;
10713   u8 *l2 = 0;
10714   u8 *l3 = 0;
10715   u8 *l4 = 0;
10716   int i;
10717
10718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10719     {
10720       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10721         ;
10722       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10723         ;
10724       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10725         ;
10726       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10727         ;
10728       else
10729         break;
10730     }
10731
10732   if (l4 && !l3)
10733     {
10734       vec_free (mask);
10735       vec_free (l2);
10736       vec_free (l4);
10737       return 0;
10738     }
10739
10740   if (mask || l2 || l3 || l4)
10741     {
10742       if (l2 || l3 || l4)
10743         {
10744           /* "With a free Ethernet header in every package" */
10745           if (l2 == 0)
10746             vec_validate (l2, 13);
10747           mask = l2;
10748           if (vec_len (l3))
10749             {
10750               vec_append (mask, l3);
10751               vec_free (l3);
10752             }
10753           if (vec_len (l4))
10754             {
10755               vec_append (mask, l4);
10756               vec_free (l4);
10757             }
10758         }
10759
10760       /* Scan forward looking for the first significant mask octet */
10761       for (i = 0; i < vec_len (mask); i++)
10762         if (mask[i])
10763           break;
10764
10765       /* compute (skip, match) params */
10766       *skipp = i / sizeof (u32x4);
10767       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10768
10769       /* Pad mask to an even multiple of the vector size */
10770       while (vec_len (mask) % sizeof (u32x4))
10771         vec_add1 (mask, 0);
10772
10773       match = vec_len (mask) / sizeof (u32x4);
10774
10775       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10776         {
10777           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10778           if (*tmp || *(tmp + 1))
10779             break;
10780           match--;
10781         }
10782       if (match == 0)
10783         clib_warning ("BUG: match 0");
10784
10785       _vec_len (mask) = match * sizeof (u32x4);
10786
10787       *matchp = match;
10788       *maskp = mask;
10789
10790       return 1;
10791     }
10792
10793   return 0;
10794 }
10795 #endif /* VPP_API_TEST_BUILTIN */
10796
10797 #define foreach_l2_next                         \
10798 _(drop, DROP)                                   \
10799 _(ethernet, ETHERNET_INPUT)                     \
10800 _(ip4, IP4_INPUT)                               \
10801 _(ip6, IP6_INPUT)
10802
10803 uword
10804 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10805 {
10806   u32 *miss_next_indexp = va_arg (*args, u32 *);
10807   u32 next_index = 0;
10808   u32 tmp;
10809
10810 #define _(n,N) \
10811   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10812   foreach_l2_next;
10813 #undef _
10814
10815   if (unformat (input, "%d", &tmp))
10816     {
10817       next_index = tmp;
10818       goto out;
10819     }
10820
10821   return 0;
10822
10823 out:
10824   *miss_next_indexp = next_index;
10825   return 1;
10826 }
10827
10828 #define foreach_ip_next                         \
10829 _(drop, DROP)                                   \
10830 _(local, LOCAL)                                 \
10831 _(rewrite, REWRITE)
10832
10833 uword
10834 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10835 {
10836   u32 *miss_next_indexp = va_arg (*args, u32 *);
10837   u32 next_index = 0;
10838   u32 tmp;
10839
10840 #define _(n,N) \
10841   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10842   foreach_ip_next;
10843 #undef _
10844
10845   if (unformat (input, "%d", &tmp))
10846     {
10847       next_index = tmp;
10848       goto out;
10849     }
10850
10851   return 0;
10852
10853 out:
10854   *miss_next_indexp = next_index;
10855   return 1;
10856 }
10857
10858 #define foreach_acl_next                        \
10859 _(deny, DENY)
10860
10861 uword
10862 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10863 {
10864   u32 *miss_next_indexp = va_arg (*args, u32 *);
10865   u32 next_index = 0;
10866   u32 tmp;
10867
10868 #define _(n,N) \
10869   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10870   foreach_acl_next;
10871 #undef _
10872
10873   if (unformat (input, "permit"))
10874     {
10875       next_index = ~0;
10876       goto out;
10877     }
10878   else if (unformat (input, "%d", &tmp))
10879     {
10880       next_index = tmp;
10881       goto out;
10882     }
10883
10884   return 0;
10885
10886 out:
10887   *miss_next_indexp = next_index;
10888   return 1;
10889 }
10890
10891 uword
10892 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10893 {
10894   u32 *r = va_arg (*args, u32 *);
10895
10896   if (unformat (input, "conform-color"))
10897     *r = POLICE_CONFORM;
10898   else if (unformat (input, "exceed-color"))
10899     *r = POLICE_EXCEED;
10900   else
10901     return 0;
10902
10903   return 1;
10904 }
10905
10906 static int
10907 api_classify_add_del_table (vat_main_t * vam)
10908 {
10909   unformat_input_t *i = vam->input;
10910   vl_api_classify_add_del_table_t *mp;
10911
10912   u32 nbuckets = 2;
10913   u32 skip = ~0;
10914   u32 match = ~0;
10915   int is_add = 1;
10916   int del_chain = 0;
10917   u32 table_index = ~0;
10918   u32 next_table_index = ~0;
10919   u32 miss_next_index = ~0;
10920   u32 memory_size = 32 << 20;
10921   u8 *mask = 0;
10922   u32 current_data_flag = 0;
10923   int current_data_offset = 0;
10924   int ret;
10925
10926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10927     {
10928       if (unformat (i, "del"))
10929         is_add = 0;
10930       else if (unformat (i, "del-chain"))
10931         {
10932           is_add = 0;
10933           del_chain = 1;
10934         }
10935       else if (unformat (i, "buckets %d", &nbuckets))
10936         ;
10937       else if (unformat (i, "memory_size %d", &memory_size))
10938         ;
10939       else if (unformat (i, "skip %d", &skip))
10940         ;
10941       else if (unformat (i, "match %d", &match))
10942         ;
10943       else if (unformat (i, "table %d", &table_index))
10944         ;
10945       else if (unformat (i, "mask %U", unformat_classify_mask,
10946                          &mask, &skip, &match))
10947         ;
10948       else if (unformat (i, "next-table %d", &next_table_index))
10949         ;
10950       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10951                          &miss_next_index))
10952         ;
10953       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10954                          &miss_next_index))
10955         ;
10956       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10957                          &miss_next_index))
10958         ;
10959       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10960         ;
10961       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10962         ;
10963       else
10964         break;
10965     }
10966
10967   if (is_add && mask == 0)
10968     {
10969       errmsg ("Mask required");
10970       return -99;
10971     }
10972
10973   if (is_add && skip == ~0)
10974     {
10975       errmsg ("skip count required");
10976       return -99;
10977     }
10978
10979   if (is_add && match == ~0)
10980     {
10981       errmsg ("match count required");
10982       return -99;
10983     }
10984
10985   if (!is_add && table_index == ~0)
10986     {
10987       errmsg ("table index required for delete");
10988       return -99;
10989     }
10990
10991   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10992
10993   mp->is_add = is_add;
10994   mp->del_chain = del_chain;
10995   mp->table_index = ntohl (table_index);
10996   mp->nbuckets = ntohl (nbuckets);
10997   mp->memory_size = ntohl (memory_size);
10998   mp->skip_n_vectors = ntohl (skip);
10999   mp->match_n_vectors = ntohl (match);
11000   mp->next_table_index = ntohl (next_table_index);
11001   mp->miss_next_index = ntohl (miss_next_index);
11002   mp->current_data_flag = ntohl (current_data_flag);
11003   mp->current_data_offset = ntohl (current_data_offset);
11004   mp->mask_len = ntohl (vec_len (mask));
11005   clib_memcpy (mp->mask, mask, vec_len (mask));
11006
11007   vec_free (mask);
11008
11009   S (mp);
11010   W (ret);
11011   return ret;
11012 }
11013
11014 #if VPP_API_TEST_BUILTIN == 0
11015 uword
11016 unformat_l4_match (unformat_input_t * input, va_list * args)
11017 {
11018   u8 **matchp = va_arg (*args, u8 **);
11019
11020   u8 *proto_header = 0;
11021   int src_port = 0;
11022   int dst_port = 0;
11023
11024   tcpudp_header_t h;
11025
11026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11027     {
11028       if (unformat (input, "src_port %d", &src_port))
11029         ;
11030       else if (unformat (input, "dst_port %d", &dst_port))
11031         ;
11032       else
11033         return 0;
11034     }
11035
11036   h.src_port = clib_host_to_net_u16 (src_port);
11037   h.dst_port = clib_host_to_net_u16 (dst_port);
11038   vec_validate (proto_header, sizeof (h) - 1);
11039   memcpy (proto_header, &h, sizeof (h));
11040
11041   *matchp = proto_header;
11042
11043   return 1;
11044 }
11045
11046 uword
11047 unformat_ip4_match (unformat_input_t * input, va_list * args)
11048 {
11049   u8 **matchp = va_arg (*args, u8 **);
11050   u8 *match = 0;
11051   ip4_header_t *ip;
11052   int version = 0;
11053   u32 version_val;
11054   int hdr_length = 0;
11055   u32 hdr_length_val;
11056   int src = 0, dst = 0;
11057   ip4_address_t src_val, dst_val;
11058   int proto = 0;
11059   u32 proto_val;
11060   int tos = 0;
11061   u32 tos_val;
11062   int length = 0;
11063   u32 length_val;
11064   int fragment_id = 0;
11065   u32 fragment_id_val;
11066   int ttl = 0;
11067   int ttl_val;
11068   int checksum = 0;
11069   u32 checksum_val;
11070
11071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11072     {
11073       if (unformat (input, "version %d", &version_val))
11074         version = 1;
11075       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11076         hdr_length = 1;
11077       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11078         src = 1;
11079       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11080         dst = 1;
11081       else if (unformat (input, "proto %d", &proto_val))
11082         proto = 1;
11083       else if (unformat (input, "tos %d", &tos_val))
11084         tos = 1;
11085       else if (unformat (input, "length %d", &length_val))
11086         length = 1;
11087       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11088         fragment_id = 1;
11089       else if (unformat (input, "ttl %d", &ttl_val))
11090         ttl = 1;
11091       else if (unformat (input, "checksum %d", &checksum_val))
11092         checksum = 1;
11093       else
11094         break;
11095     }
11096
11097   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11098       + ttl + checksum == 0)
11099     return 0;
11100
11101   /*
11102    * Aligned because we use the real comparison functions
11103    */
11104   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11105
11106   ip = (ip4_header_t *) match;
11107
11108   /* These are realistically matched in practice */
11109   if (src)
11110     ip->src_address.as_u32 = src_val.as_u32;
11111
11112   if (dst)
11113     ip->dst_address.as_u32 = dst_val.as_u32;
11114
11115   if (proto)
11116     ip->protocol = proto_val;
11117
11118
11119   /* These are not, but they're included for completeness */
11120   if (version)
11121     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11122
11123   if (hdr_length)
11124     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11125
11126   if (tos)
11127     ip->tos = tos_val;
11128
11129   if (length)
11130     ip->length = clib_host_to_net_u16 (length_val);
11131
11132   if (ttl)
11133     ip->ttl = ttl_val;
11134
11135   if (checksum)
11136     ip->checksum = clib_host_to_net_u16 (checksum_val);
11137
11138   *matchp = match;
11139   return 1;
11140 }
11141
11142 uword
11143 unformat_ip6_match (unformat_input_t * input, va_list * args)
11144 {
11145   u8 **matchp = va_arg (*args, u8 **);
11146   u8 *match = 0;
11147   ip6_header_t *ip;
11148   int version = 0;
11149   u32 version_val;
11150   u8 traffic_class = 0;
11151   u32 traffic_class_val = 0;
11152   u8 flow_label = 0;
11153   u8 flow_label_val;
11154   int src = 0, dst = 0;
11155   ip6_address_t src_val, dst_val;
11156   int proto = 0;
11157   u32 proto_val;
11158   int payload_length = 0;
11159   u32 payload_length_val;
11160   int hop_limit = 0;
11161   int hop_limit_val;
11162   u32 ip_version_traffic_class_and_flow_label;
11163
11164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11165     {
11166       if (unformat (input, "version %d", &version_val))
11167         version = 1;
11168       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11169         traffic_class = 1;
11170       else if (unformat (input, "flow_label %d", &flow_label_val))
11171         flow_label = 1;
11172       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11173         src = 1;
11174       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11175         dst = 1;
11176       else if (unformat (input, "proto %d", &proto_val))
11177         proto = 1;
11178       else if (unformat (input, "payload_length %d", &payload_length_val))
11179         payload_length = 1;
11180       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11181         hop_limit = 1;
11182       else
11183         break;
11184     }
11185
11186   if (version + traffic_class + flow_label + src + dst + proto +
11187       payload_length + hop_limit == 0)
11188     return 0;
11189
11190   /*
11191    * Aligned because we use the real comparison functions
11192    */
11193   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11194
11195   ip = (ip6_header_t *) match;
11196
11197   if (src)
11198     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11199
11200   if (dst)
11201     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11202
11203   if (proto)
11204     ip->protocol = proto_val;
11205
11206   ip_version_traffic_class_and_flow_label = 0;
11207
11208   if (version)
11209     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11210
11211   if (traffic_class)
11212     ip_version_traffic_class_and_flow_label |=
11213       (traffic_class_val & 0xFF) << 20;
11214
11215   if (flow_label)
11216     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11217
11218   ip->ip_version_traffic_class_and_flow_label =
11219     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11220
11221   if (payload_length)
11222     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11223
11224   if (hop_limit)
11225     ip->hop_limit = hop_limit_val;
11226
11227   *matchp = match;
11228   return 1;
11229 }
11230
11231 uword
11232 unformat_l3_match (unformat_input_t * input, va_list * args)
11233 {
11234   u8 **matchp = va_arg (*args, u8 **);
11235
11236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11237     {
11238       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11239         return 1;
11240       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11241         return 1;
11242       else
11243         break;
11244     }
11245   return 0;
11246 }
11247
11248 uword
11249 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11250 {
11251   u8 *tagp = va_arg (*args, u8 *);
11252   u32 tag;
11253
11254   if (unformat (input, "%d", &tag))
11255     {
11256       tagp[0] = (tag >> 8) & 0x0F;
11257       tagp[1] = tag & 0xFF;
11258       return 1;
11259     }
11260
11261   return 0;
11262 }
11263
11264 uword
11265 unformat_l2_match (unformat_input_t * input, va_list * args)
11266 {
11267   u8 **matchp = va_arg (*args, u8 **);
11268   u8 *match = 0;
11269   u8 src = 0;
11270   u8 src_val[6];
11271   u8 dst = 0;
11272   u8 dst_val[6];
11273   u8 proto = 0;
11274   u16 proto_val;
11275   u8 tag1 = 0;
11276   u8 tag1_val[2];
11277   u8 tag2 = 0;
11278   u8 tag2_val[2];
11279   int len = 14;
11280   u8 ignore_tag1 = 0;
11281   u8 ignore_tag2 = 0;
11282   u8 cos1 = 0;
11283   u8 cos2 = 0;
11284   u32 cos1_val = 0;
11285   u32 cos2_val = 0;
11286
11287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11288     {
11289       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11290         src = 1;
11291       else
11292         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11293         dst = 1;
11294       else if (unformat (input, "proto %U",
11295                          unformat_ethernet_type_host_byte_order, &proto_val))
11296         proto = 1;
11297       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11298         tag1 = 1;
11299       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11300         tag2 = 1;
11301       else if (unformat (input, "ignore-tag1"))
11302         ignore_tag1 = 1;
11303       else if (unformat (input, "ignore-tag2"))
11304         ignore_tag2 = 1;
11305       else if (unformat (input, "cos1 %d", &cos1_val))
11306         cos1 = 1;
11307       else if (unformat (input, "cos2 %d", &cos2_val))
11308         cos2 = 1;
11309       else
11310         break;
11311     }
11312   if ((src + dst + proto + tag1 + tag2 +
11313        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11314     return 0;
11315
11316   if (tag1 || ignore_tag1 || cos1)
11317     len = 18;
11318   if (tag2 || ignore_tag2 || cos2)
11319     len = 22;
11320
11321   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11322
11323   if (dst)
11324     clib_memcpy (match, dst_val, 6);
11325
11326   if (src)
11327     clib_memcpy (match + 6, src_val, 6);
11328
11329   if (tag2)
11330     {
11331       /* inner vlan tag */
11332       match[19] = tag2_val[1];
11333       match[18] = tag2_val[0];
11334       if (cos2)
11335         match[18] |= (cos2_val & 0x7) << 5;
11336       if (proto)
11337         {
11338           match[21] = proto_val & 0xff;
11339           match[20] = proto_val >> 8;
11340         }
11341       if (tag1)
11342         {
11343           match[15] = tag1_val[1];
11344           match[14] = tag1_val[0];
11345         }
11346       if (cos1)
11347         match[14] |= (cos1_val & 0x7) << 5;
11348       *matchp = match;
11349       return 1;
11350     }
11351   if (tag1)
11352     {
11353       match[15] = tag1_val[1];
11354       match[14] = tag1_val[0];
11355       if (proto)
11356         {
11357           match[17] = proto_val & 0xff;
11358           match[16] = proto_val >> 8;
11359         }
11360       if (cos1)
11361         match[14] |= (cos1_val & 0x7) << 5;
11362
11363       *matchp = match;
11364       return 1;
11365     }
11366   if (cos2)
11367     match[18] |= (cos2_val & 0x7) << 5;
11368   if (cos1)
11369     match[14] |= (cos1_val & 0x7) << 5;
11370   if (proto)
11371     {
11372       match[13] = proto_val & 0xff;
11373       match[12] = proto_val >> 8;
11374     }
11375
11376   *matchp = match;
11377   return 1;
11378 }
11379
11380 uword
11381 unformat_qos_source (unformat_input_t * input, va_list * args)
11382 {
11383   int *qs = va_arg (*args, int *);
11384
11385   if (unformat (input, "ip"))
11386     *qs = QOS_SOURCE_IP;
11387   else if (unformat (input, "mpls"))
11388     *qs = QOS_SOURCE_MPLS;
11389   else if (unformat (input, "ext"))
11390     *qs = QOS_SOURCE_EXT;
11391   else if (unformat (input, "vlan"))
11392     *qs = QOS_SOURCE_VLAN;
11393   else
11394     return 0;
11395
11396   return 1;
11397 }
11398 #endif
11399
11400 uword
11401 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11402 {
11403   u8 **matchp = va_arg (*args, u8 **);
11404   u32 skip_n_vectors = va_arg (*args, u32);
11405   u32 match_n_vectors = va_arg (*args, u32);
11406
11407   u8 *match = 0;
11408   u8 *l2 = 0;
11409   u8 *l3 = 0;
11410   u8 *l4 = 0;
11411
11412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11413     {
11414       if (unformat (input, "hex %U", unformat_hex_string, &match))
11415         ;
11416       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11417         ;
11418       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11419         ;
11420       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11421         ;
11422       else
11423         break;
11424     }
11425
11426   if (l4 && !l3)
11427     {
11428       vec_free (match);
11429       vec_free (l2);
11430       vec_free (l4);
11431       return 0;
11432     }
11433
11434   if (match || l2 || l3 || l4)
11435     {
11436       if (l2 || l3 || l4)
11437         {
11438           /* "Win a free Ethernet header in every packet" */
11439           if (l2 == 0)
11440             vec_validate_aligned (l2, 13, sizeof (u32x4));
11441           match = l2;
11442           if (vec_len (l3))
11443             {
11444               vec_append_aligned (match, l3, sizeof (u32x4));
11445               vec_free (l3);
11446             }
11447           if (vec_len (l4))
11448             {
11449               vec_append_aligned (match, l4, sizeof (u32x4));
11450               vec_free (l4);
11451             }
11452         }
11453
11454       /* Make sure the vector is big enough even if key is all 0's */
11455       vec_validate_aligned
11456         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11457          sizeof (u32x4));
11458
11459       /* Set size, include skipped vectors */
11460       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11461
11462       *matchp = match;
11463
11464       return 1;
11465     }
11466
11467   return 0;
11468 }
11469
11470 static int
11471 api_classify_add_del_session (vat_main_t * vam)
11472 {
11473   unformat_input_t *i = vam->input;
11474   vl_api_classify_add_del_session_t *mp;
11475   int is_add = 1;
11476   u32 table_index = ~0;
11477   u32 hit_next_index = ~0;
11478   u32 opaque_index = ~0;
11479   u8 *match = 0;
11480   i32 advance = 0;
11481   u32 skip_n_vectors = 0;
11482   u32 match_n_vectors = 0;
11483   u32 action = 0;
11484   u32 metadata = 0;
11485   int ret;
11486
11487   /*
11488    * Warning: you have to supply skip_n and match_n
11489    * because the API client cant simply look at the classify
11490    * table object.
11491    */
11492
11493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11494     {
11495       if (unformat (i, "del"))
11496         is_add = 0;
11497       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11498                          &hit_next_index))
11499         ;
11500       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11501                          &hit_next_index))
11502         ;
11503       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11504                          &hit_next_index))
11505         ;
11506       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11507         ;
11508       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11509         ;
11510       else if (unformat (i, "opaque-index %d", &opaque_index))
11511         ;
11512       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11513         ;
11514       else if (unformat (i, "match_n %d", &match_n_vectors))
11515         ;
11516       else if (unformat (i, "match %U", api_unformat_classify_match,
11517                          &match, skip_n_vectors, match_n_vectors))
11518         ;
11519       else if (unformat (i, "advance %d", &advance))
11520         ;
11521       else if (unformat (i, "table-index %d", &table_index))
11522         ;
11523       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11524         action = 1;
11525       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11526         action = 2;
11527       else if (unformat (i, "action %d", &action))
11528         ;
11529       else if (unformat (i, "metadata %d", &metadata))
11530         ;
11531       else
11532         break;
11533     }
11534
11535   if (table_index == ~0)
11536     {
11537       errmsg ("Table index required");
11538       return -99;
11539     }
11540
11541   if (is_add && match == 0)
11542     {
11543       errmsg ("Match value required");
11544       return -99;
11545     }
11546
11547   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11548
11549   mp->is_add = is_add;
11550   mp->table_index = ntohl (table_index);
11551   mp->hit_next_index = ntohl (hit_next_index);
11552   mp->opaque_index = ntohl (opaque_index);
11553   mp->advance = ntohl (advance);
11554   mp->action = action;
11555   mp->metadata = ntohl (metadata);
11556   mp->match_len = ntohl (vec_len (match));
11557   clib_memcpy (mp->match, match, vec_len (match));
11558   vec_free (match);
11559
11560   S (mp);
11561   W (ret);
11562   return ret;
11563 }
11564
11565 static int
11566 api_classify_set_interface_ip_table (vat_main_t * vam)
11567 {
11568   unformat_input_t *i = vam->input;
11569   vl_api_classify_set_interface_ip_table_t *mp;
11570   u32 sw_if_index;
11571   int sw_if_index_set;
11572   u32 table_index = ~0;
11573   u8 is_ipv6 = 0;
11574   int ret;
11575
11576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11579         sw_if_index_set = 1;
11580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11581         sw_if_index_set = 1;
11582       else if (unformat (i, "table %d", &table_index))
11583         ;
11584       else
11585         {
11586           clib_warning ("parse error '%U'", format_unformat_error, i);
11587           return -99;
11588         }
11589     }
11590
11591   if (sw_if_index_set == 0)
11592     {
11593       errmsg ("missing interface name or sw_if_index");
11594       return -99;
11595     }
11596
11597
11598   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11599
11600   mp->sw_if_index = ntohl (sw_if_index);
11601   mp->table_index = ntohl (table_index);
11602   mp->is_ipv6 = is_ipv6;
11603
11604   S (mp);
11605   W (ret);
11606   return ret;
11607 }
11608
11609 static int
11610 api_classify_set_interface_l2_tables (vat_main_t * vam)
11611 {
11612   unformat_input_t *i = vam->input;
11613   vl_api_classify_set_interface_l2_tables_t *mp;
11614   u32 sw_if_index;
11615   int sw_if_index_set;
11616   u32 ip4_table_index = ~0;
11617   u32 ip6_table_index = ~0;
11618   u32 other_table_index = ~0;
11619   u32 is_input = 1;
11620   int ret;
11621
11622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11623     {
11624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11625         sw_if_index_set = 1;
11626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11627         sw_if_index_set = 1;
11628       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11629         ;
11630       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11631         ;
11632       else if (unformat (i, "other-table %d", &other_table_index))
11633         ;
11634       else if (unformat (i, "is-input %d", &is_input))
11635         ;
11636       else
11637         {
11638           clib_warning ("parse error '%U'", format_unformat_error, i);
11639           return -99;
11640         }
11641     }
11642
11643   if (sw_if_index_set == 0)
11644     {
11645       errmsg ("missing interface name or sw_if_index");
11646       return -99;
11647     }
11648
11649
11650   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11651
11652   mp->sw_if_index = ntohl (sw_if_index);
11653   mp->ip4_table_index = ntohl (ip4_table_index);
11654   mp->ip6_table_index = ntohl (ip6_table_index);
11655   mp->other_table_index = ntohl (other_table_index);
11656   mp->is_input = (u8) is_input;
11657
11658   S (mp);
11659   W (ret);
11660   return ret;
11661 }
11662
11663 static int
11664 api_set_ipfix_exporter (vat_main_t * vam)
11665 {
11666   unformat_input_t *i = vam->input;
11667   vl_api_set_ipfix_exporter_t *mp;
11668   ip4_address_t collector_address;
11669   u8 collector_address_set = 0;
11670   u32 collector_port = ~0;
11671   ip4_address_t src_address;
11672   u8 src_address_set = 0;
11673   u32 vrf_id = ~0;
11674   u32 path_mtu = ~0;
11675   u32 template_interval = ~0;
11676   u8 udp_checksum = 0;
11677   int ret;
11678
11679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (i, "collector_address %U", unformat_ip4_address,
11682                     &collector_address))
11683         collector_address_set = 1;
11684       else if (unformat (i, "collector_port %d", &collector_port))
11685         ;
11686       else if (unformat (i, "src_address %U", unformat_ip4_address,
11687                          &src_address))
11688         src_address_set = 1;
11689       else if (unformat (i, "vrf_id %d", &vrf_id))
11690         ;
11691       else if (unformat (i, "path_mtu %d", &path_mtu))
11692         ;
11693       else if (unformat (i, "template_interval %d", &template_interval))
11694         ;
11695       else if (unformat (i, "udp_checksum"))
11696         udp_checksum = 1;
11697       else
11698         break;
11699     }
11700
11701   if (collector_address_set == 0)
11702     {
11703       errmsg ("collector_address required");
11704       return -99;
11705     }
11706
11707   if (src_address_set == 0)
11708     {
11709       errmsg ("src_address required");
11710       return -99;
11711     }
11712
11713   M (SET_IPFIX_EXPORTER, mp);
11714
11715   memcpy (mp->collector_address, collector_address.data,
11716           sizeof (collector_address.data));
11717   mp->collector_port = htons ((u16) collector_port);
11718   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11719   mp->vrf_id = htonl (vrf_id);
11720   mp->path_mtu = htonl (path_mtu);
11721   mp->template_interval = htonl (template_interval);
11722   mp->udp_checksum = udp_checksum;
11723
11724   S (mp);
11725   W (ret);
11726   return ret;
11727 }
11728
11729 static int
11730 api_set_ipfix_classify_stream (vat_main_t * vam)
11731 {
11732   unformat_input_t *i = vam->input;
11733   vl_api_set_ipfix_classify_stream_t *mp;
11734   u32 domain_id = 0;
11735   u32 src_port = UDP_DST_PORT_ipfix;
11736   int ret;
11737
11738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11739     {
11740       if (unformat (i, "domain %d", &domain_id))
11741         ;
11742       else if (unformat (i, "src_port %d", &src_port))
11743         ;
11744       else
11745         {
11746           errmsg ("unknown input `%U'", format_unformat_error, i);
11747           return -99;
11748         }
11749     }
11750
11751   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11752
11753   mp->domain_id = htonl (domain_id);
11754   mp->src_port = htons ((u16) src_port);
11755
11756   S (mp);
11757   W (ret);
11758   return ret;
11759 }
11760
11761 static int
11762 api_ipfix_classify_table_add_del (vat_main_t * vam)
11763 {
11764   unformat_input_t *i = vam->input;
11765   vl_api_ipfix_classify_table_add_del_t *mp;
11766   int is_add = -1;
11767   u32 classify_table_index = ~0;
11768   u8 ip_version = 0;
11769   u8 transport_protocol = 255;
11770   int ret;
11771
11772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11773     {
11774       if (unformat (i, "add"))
11775         is_add = 1;
11776       else if (unformat (i, "del"))
11777         is_add = 0;
11778       else if (unformat (i, "table %d", &classify_table_index))
11779         ;
11780       else if (unformat (i, "ip4"))
11781         ip_version = 4;
11782       else if (unformat (i, "ip6"))
11783         ip_version = 6;
11784       else if (unformat (i, "tcp"))
11785         transport_protocol = 6;
11786       else if (unformat (i, "udp"))
11787         transport_protocol = 17;
11788       else
11789         {
11790           errmsg ("unknown input `%U'", format_unformat_error, i);
11791           return -99;
11792         }
11793     }
11794
11795   if (is_add == -1)
11796     {
11797       errmsg ("expecting: add|del");
11798       return -99;
11799     }
11800   if (classify_table_index == ~0)
11801     {
11802       errmsg ("classifier table not specified");
11803       return -99;
11804     }
11805   if (ip_version == 0)
11806     {
11807       errmsg ("IP version not specified");
11808       return -99;
11809     }
11810
11811   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11812
11813   mp->is_add = is_add;
11814   mp->table_id = htonl (classify_table_index);
11815   mp->ip_version = ip_version;
11816   mp->transport_protocol = transport_protocol;
11817
11818   S (mp);
11819   W (ret);
11820   return ret;
11821 }
11822
11823 static int
11824 api_get_node_index (vat_main_t * vam)
11825 {
11826   unformat_input_t *i = vam->input;
11827   vl_api_get_node_index_t *mp;
11828   u8 *name = 0;
11829   int ret;
11830
11831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (i, "node %s", &name))
11834         ;
11835       else
11836         break;
11837     }
11838   if (name == 0)
11839     {
11840       errmsg ("node name required");
11841       return -99;
11842     }
11843   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11844     {
11845       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11846       return -99;
11847     }
11848
11849   M (GET_NODE_INDEX, mp);
11850   clib_memcpy (mp->node_name, name, vec_len (name));
11851   vec_free (name);
11852
11853   S (mp);
11854   W (ret);
11855   return ret;
11856 }
11857
11858 static int
11859 api_get_next_index (vat_main_t * vam)
11860 {
11861   unformat_input_t *i = vam->input;
11862   vl_api_get_next_index_t *mp;
11863   u8 *node_name = 0, *next_node_name = 0;
11864   int ret;
11865
11866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11867     {
11868       if (unformat (i, "node-name %s", &node_name))
11869         ;
11870       else if (unformat (i, "next-node-name %s", &next_node_name))
11871         break;
11872     }
11873
11874   if (node_name == 0)
11875     {
11876       errmsg ("node name required");
11877       return -99;
11878     }
11879   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11880     {
11881       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11882       return -99;
11883     }
11884
11885   if (next_node_name == 0)
11886     {
11887       errmsg ("next node name required");
11888       return -99;
11889     }
11890   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11891     {
11892       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11893       return -99;
11894     }
11895
11896   M (GET_NEXT_INDEX, mp);
11897   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11898   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11899   vec_free (node_name);
11900   vec_free (next_node_name);
11901
11902   S (mp);
11903   W (ret);
11904   return ret;
11905 }
11906
11907 static int
11908 api_add_node_next (vat_main_t * vam)
11909 {
11910   unformat_input_t *i = vam->input;
11911   vl_api_add_node_next_t *mp;
11912   u8 *name = 0;
11913   u8 *next = 0;
11914   int ret;
11915
11916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11917     {
11918       if (unformat (i, "node %s", &name))
11919         ;
11920       else if (unformat (i, "next %s", &next))
11921         ;
11922       else
11923         break;
11924     }
11925   if (name == 0)
11926     {
11927       errmsg ("node name required");
11928       return -99;
11929     }
11930   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11931     {
11932       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11933       return -99;
11934     }
11935   if (next == 0)
11936     {
11937       errmsg ("next node required");
11938       return -99;
11939     }
11940   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11941     {
11942       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11943       return -99;
11944     }
11945
11946   M (ADD_NODE_NEXT, mp);
11947   clib_memcpy (mp->node_name, name, vec_len (name));
11948   clib_memcpy (mp->next_name, next, vec_len (next));
11949   vec_free (name);
11950   vec_free (next);
11951
11952   S (mp);
11953   W (ret);
11954   return ret;
11955 }
11956
11957 static int
11958 api_l2tpv3_create_tunnel (vat_main_t * vam)
11959 {
11960   unformat_input_t *i = vam->input;
11961   ip6_address_t client_address, our_address;
11962   int client_address_set = 0;
11963   int our_address_set = 0;
11964   u32 local_session_id = 0;
11965   u32 remote_session_id = 0;
11966   u64 local_cookie = 0;
11967   u64 remote_cookie = 0;
11968   u8 l2_sublayer_present = 0;
11969   vl_api_l2tpv3_create_tunnel_t *mp;
11970   int ret;
11971
11972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11973     {
11974       if (unformat (i, "client_address %U", unformat_ip6_address,
11975                     &client_address))
11976         client_address_set = 1;
11977       else if (unformat (i, "our_address %U", unformat_ip6_address,
11978                          &our_address))
11979         our_address_set = 1;
11980       else if (unformat (i, "local_session_id %d", &local_session_id))
11981         ;
11982       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11983         ;
11984       else if (unformat (i, "local_cookie %lld", &local_cookie))
11985         ;
11986       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11987         ;
11988       else if (unformat (i, "l2-sublayer-present"))
11989         l2_sublayer_present = 1;
11990       else
11991         break;
11992     }
11993
11994   if (client_address_set == 0)
11995     {
11996       errmsg ("client_address required");
11997       return -99;
11998     }
11999
12000   if (our_address_set == 0)
12001     {
12002       errmsg ("our_address required");
12003       return -99;
12004     }
12005
12006   M (L2TPV3_CREATE_TUNNEL, mp);
12007
12008   clib_memcpy (mp->client_address, client_address.as_u8,
12009                sizeof (mp->client_address));
12010
12011   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12012
12013   mp->local_session_id = ntohl (local_session_id);
12014   mp->remote_session_id = ntohl (remote_session_id);
12015   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12016   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12017   mp->l2_sublayer_present = l2_sublayer_present;
12018   mp->is_ipv6 = 1;
12019
12020   S (mp);
12021   W (ret);
12022   return ret;
12023 }
12024
12025 static int
12026 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12027 {
12028   unformat_input_t *i = vam->input;
12029   u32 sw_if_index;
12030   u8 sw_if_index_set = 0;
12031   u64 new_local_cookie = 0;
12032   u64 new_remote_cookie = 0;
12033   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12034   int ret;
12035
12036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12037     {
12038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12039         sw_if_index_set = 1;
12040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12041         sw_if_index_set = 1;
12042       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12043         ;
12044       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12045         ;
12046       else
12047         break;
12048     }
12049
12050   if (sw_if_index_set == 0)
12051     {
12052       errmsg ("missing interface name or sw_if_index");
12053       return -99;
12054     }
12055
12056   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12057
12058   mp->sw_if_index = ntohl (sw_if_index);
12059   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12060   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12061
12062   S (mp);
12063   W (ret);
12064   return ret;
12065 }
12066
12067 static int
12068 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12069 {
12070   unformat_input_t *i = vam->input;
12071   vl_api_l2tpv3_interface_enable_disable_t *mp;
12072   u32 sw_if_index;
12073   u8 sw_if_index_set = 0;
12074   u8 enable_disable = 1;
12075   int ret;
12076
12077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12078     {
12079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12080         sw_if_index_set = 1;
12081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12082         sw_if_index_set = 1;
12083       else if (unformat (i, "enable"))
12084         enable_disable = 1;
12085       else if (unformat (i, "disable"))
12086         enable_disable = 0;
12087       else
12088         break;
12089     }
12090
12091   if (sw_if_index_set == 0)
12092     {
12093       errmsg ("missing interface name or sw_if_index");
12094       return -99;
12095     }
12096
12097   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12098
12099   mp->sw_if_index = ntohl (sw_if_index);
12100   mp->enable_disable = enable_disable;
12101
12102   S (mp);
12103   W (ret);
12104   return ret;
12105 }
12106
12107 static int
12108 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12109 {
12110   unformat_input_t *i = vam->input;
12111   vl_api_l2tpv3_set_lookup_key_t *mp;
12112   u8 key = ~0;
12113   int ret;
12114
12115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12116     {
12117       if (unformat (i, "lookup_v6_src"))
12118         key = L2T_LOOKUP_SRC_ADDRESS;
12119       else if (unformat (i, "lookup_v6_dst"))
12120         key = L2T_LOOKUP_DST_ADDRESS;
12121       else if (unformat (i, "lookup_session_id"))
12122         key = L2T_LOOKUP_SESSION_ID;
12123       else
12124         break;
12125     }
12126
12127   if (key == (u8) ~ 0)
12128     {
12129       errmsg ("l2tp session lookup key unset");
12130       return -99;
12131     }
12132
12133   M (L2TPV3_SET_LOOKUP_KEY, mp);
12134
12135   mp->key = key;
12136
12137   S (mp);
12138   W (ret);
12139   return ret;
12140 }
12141
12142 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12143   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12144 {
12145   vat_main_t *vam = &vat_main;
12146
12147   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12148          format_ip6_address, mp->our_address,
12149          format_ip6_address, mp->client_address,
12150          clib_net_to_host_u32 (mp->sw_if_index));
12151
12152   print (vam->ofp,
12153          "   local cookies %016llx %016llx remote cookie %016llx",
12154          clib_net_to_host_u64 (mp->local_cookie[0]),
12155          clib_net_to_host_u64 (mp->local_cookie[1]),
12156          clib_net_to_host_u64 (mp->remote_cookie));
12157
12158   print (vam->ofp, "   local session-id %d remote session-id %d",
12159          clib_net_to_host_u32 (mp->local_session_id),
12160          clib_net_to_host_u32 (mp->remote_session_id));
12161
12162   print (vam->ofp, "   l2 specific sublayer %s\n",
12163          mp->l2_sublayer_present ? "preset" : "absent");
12164
12165 }
12166
12167 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12168   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12169 {
12170   vat_main_t *vam = &vat_main;
12171   vat_json_node_t *node = NULL;
12172   struct in6_addr addr;
12173
12174   if (VAT_JSON_ARRAY != vam->json_tree.type)
12175     {
12176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12177       vat_json_init_array (&vam->json_tree);
12178     }
12179   node = vat_json_array_add (&vam->json_tree);
12180
12181   vat_json_init_object (node);
12182
12183   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12184   vat_json_object_add_ip6 (node, "our_address", addr);
12185   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12186   vat_json_object_add_ip6 (node, "client_address", addr);
12187
12188   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12189   vat_json_init_array (lc);
12190   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12191   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12192   vat_json_object_add_uint (node, "remote_cookie",
12193                             clib_net_to_host_u64 (mp->remote_cookie));
12194
12195   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12196   vat_json_object_add_uint (node, "local_session_id",
12197                             clib_net_to_host_u32 (mp->local_session_id));
12198   vat_json_object_add_uint (node, "remote_session_id",
12199                             clib_net_to_host_u32 (mp->remote_session_id));
12200   vat_json_object_add_string_copy (node, "l2_sublayer",
12201                                    mp->l2_sublayer_present ? (u8 *) "present"
12202                                    : (u8 *) "absent");
12203 }
12204
12205 static int
12206 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12207 {
12208   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12209   vl_api_control_ping_t *mp_ping;
12210   int ret;
12211
12212   /* Get list of l2tpv3-tunnel interfaces */
12213   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12214   S (mp);
12215
12216   /* Use a control ping for synchronization */
12217   MPING (CONTROL_PING, mp_ping);
12218   S (mp_ping);
12219
12220   W (ret);
12221   return ret;
12222 }
12223
12224
12225 static void vl_api_sw_interface_tap_v2_details_t_handler
12226   (vl_api_sw_interface_tap_v2_details_t * mp)
12227 {
12228   vat_main_t *vam = &vat_main;
12229
12230   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12231                     mp->host_ip4_prefix_len);
12232   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12233                     mp->host_ip6_prefix_len);
12234
12235   print (vam->ofp,
12236          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12237          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12238          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12239          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12240          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12241
12242   vec_free (ip4);
12243   vec_free (ip6);
12244 }
12245
12246 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12247   (vl_api_sw_interface_tap_v2_details_t * mp)
12248 {
12249   vat_main_t *vam = &vat_main;
12250   vat_json_node_t *node = NULL;
12251
12252   if (VAT_JSON_ARRAY != vam->json_tree.type)
12253     {
12254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12255       vat_json_init_array (&vam->json_tree);
12256     }
12257   node = vat_json_array_add (&vam->json_tree);
12258
12259   vat_json_init_object (node);
12260   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12261   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12262   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12263   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12264   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12265   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12266   vat_json_object_add_string_copy (node, "host_mac_addr",
12267                                    format (0, "%U", format_ethernet_address,
12268                                            &mp->host_mac_addr));
12269   vat_json_object_add_string_copy (node, "host_namespace",
12270                                    mp->host_namespace);
12271   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12272   vat_json_object_add_string_copy (node, "host_ip4_addr",
12273                                    format (0, "%U/%d", format_ip4_address,
12274                                            mp->host_ip4_addr,
12275                                            mp->host_ip4_prefix_len));
12276   vat_json_object_add_string_copy (node, "host_ip6_addr",
12277                                    format (0, "%U/%d", format_ip6_address,
12278                                            mp->host_ip6_addr,
12279                                            mp->host_ip6_prefix_len));
12280
12281 }
12282
12283 static int
12284 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12285 {
12286   vl_api_sw_interface_tap_v2_dump_t *mp;
12287   vl_api_control_ping_t *mp_ping;
12288   int ret;
12289
12290   print (vam->ofp,
12291          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12292          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12293          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12294          "host_ip6_addr");
12295
12296   /* Get list of tap interfaces */
12297   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12298   S (mp);
12299
12300   /* Use a control ping for synchronization */
12301   MPING (CONTROL_PING, mp_ping);
12302   S (mp_ping);
12303
12304   W (ret);
12305   return ret;
12306 }
12307
12308 static void vl_api_sw_interface_virtio_pci_details_t_handler
12309   (vl_api_sw_interface_virtio_pci_details_t * mp)
12310 {
12311   vat_main_t *vam = &vat_main;
12312
12313   typedef union
12314   {
12315     struct
12316     {
12317       u16 domain;
12318       u8 bus;
12319       u8 slot:5;
12320       u8 function:3;
12321     };
12322     u32 as_u32;
12323   } pci_addr_t;
12324   pci_addr_t addr;
12325   addr.as_u32 = ntohl (mp->pci_addr);
12326   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12327                          addr.slot, addr.function);
12328
12329   print (vam->ofp,
12330          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12331          pci_addr, ntohl (mp->sw_if_index),
12332          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12333          format_ethernet_address, mp->mac_addr,
12334          clib_net_to_host_u64 (mp->features));
12335   vec_free (pci_addr);
12336 }
12337
12338 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12339   (vl_api_sw_interface_virtio_pci_details_t * mp)
12340 {
12341   vat_main_t *vam = &vat_main;
12342   vat_json_node_t *node = NULL;
12343
12344   if (VAT_JSON_ARRAY != vam->json_tree.type)
12345     {
12346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12347       vat_json_init_array (&vam->json_tree);
12348     }
12349   node = vat_json_array_add (&vam->json_tree);
12350
12351   vat_json_init_object (node);
12352   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12353   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12354   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12355   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12356   vat_json_object_add_uint (node, "features",
12357                             clib_net_to_host_u64 (mp->features));
12358   vat_json_object_add_string_copy (node, "mac_addr",
12359                                    format (0, "%U", format_ethernet_address,
12360                                            &mp->mac_addr));
12361 }
12362
12363 static int
12364 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12365 {
12366   vl_api_sw_interface_virtio_pci_dump_t *mp;
12367   vl_api_control_ping_t *mp_ping;
12368   int ret;
12369
12370   print (vam->ofp,
12371          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12372          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12373          "mac_addr", "features");
12374
12375   /* Get list of tap interfaces */
12376   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12377   S (mp);
12378
12379   /* Use a control ping for synchronization */
12380   MPING (CONTROL_PING, mp_ping);
12381   S (mp_ping);
12382
12383   W (ret);
12384   return ret;
12385 }
12386
12387 static int
12388 api_vxlan_offload_rx (vat_main_t * vam)
12389 {
12390   unformat_input_t *line_input = vam->input;
12391   vl_api_vxlan_offload_rx_t *mp;
12392   u32 hw_if_index = ~0, rx_if_index = ~0;
12393   u8 is_add = 1;
12394   int ret;
12395
12396   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12397     {
12398       if (unformat (line_input, "del"))
12399         is_add = 0;
12400       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12401                          &hw_if_index))
12402         ;
12403       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12404         ;
12405       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12406                          &rx_if_index))
12407         ;
12408       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12409         ;
12410       else
12411         {
12412           errmsg ("parse error '%U'", format_unformat_error, line_input);
12413           return -99;
12414         }
12415     }
12416
12417   if (hw_if_index == ~0)
12418     {
12419       errmsg ("no hw interface");
12420       return -99;
12421     }
12422
12423   if (rx_if_index == ~0)
12424     {
12425       errmsg ("no rx tunnel");
12426       return -99;
12427     }
12428
12429   M (VXLAN_OFFLOAD_RX, mp);
12430
12431   mp->hw_if_index = ntohl (hw_if_index);
12432   mp->sw_if_index = ntohl (rx_if_index);
12433   mp->enable = is_add;
12434
12435   S (mp);
12436   W (ret);
12437   return ret;
12438 }
12439
12440 static uword unformat_vxlan_decap_next
12441   (unformat_input_t * input, va_list * args)
12442 {
12443   u32 *result = va_arg (*args, u32 *);
12444   u32 tmp;
12445
12446   if (unformat (input, "l2"))
12447     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12448   else if (unformat (input, "%d", &tmp))
12449     *result = tmp;
12450   else
12451     return 0;
12452   return 1;
12453 }
12454
12455 static int
12456 api_vxlan_add_del_tunnel (vat_main_t * vam)
12457 {
12458   unformat_input_t *line_input = vam->input;
12459   vl_api_vxlan_add_del_tunnel_t *mp;
12460   ip46_address_t src, dst;
12461   u8 is_add = 1;
12462   u8 ipv4_set = 0, ipv6_set = 0;
12463   u8 src_set = 0;
12464   u8 dst_set = 0;
12465   u8 grp_set = 0;
12466   u32 instance = ~0;
12467   u32 mcast_sw_if_index = ~0;
12468   u32 encap_vrf_id = 0;
12469   u32 decap_next_index = ~0;
12470   u32 vni = 0;
12471   int ret;
12472
12473   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12474   clib_memset (&src, 0, sizeof src);
12475   clib_memset (&dst, 0, sizeof dst);
12476
12477   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12478     {
12479       if (unformat (line_input, "del"))
12480         is_add = 0;
12481       else if (unformat (line_input, "instance %d", &instance))
12482         ;
12483       else
12484         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12485         {
12486           ipv4_set = 1;
12487           src_set = 1;
12488         }
12489       else
12490         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12491         {
12492           ipv4_set = 1;
12493           dst_set = 1;
12494         }
12495       else
12496         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12497         {
12498           ipv6_set = 1;
12499           src_set = 1;
12500         }
12501       else
12502         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12503         {
12504           ipv6_set = 1;
12505           dst_set = 1;
12506         }
12507       else if (unformat (line_input, "group %U %U",
12508                          unformat_ip4_address, &dst.ip4,
12509                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12510         {
12511           grp_set = dst_set = 1;
12512           ipv4_set = 1;
12513         }
12514       else if (unformat (line_input, "group %U",
12515                          unformat_ip4_address, &dst.ip4))
12516         {
12517           grp_set = dst_set = 1;
12518           ipv4_set = 1;
12519         }
12520       else if (unformat (line_input, "group %U %U",
12521                          unformat_ip6_address, &dst.ip6,
12522                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12523         {
12524           grp_set = dst_set = 1;
12525           ipv6_set = 1;
12526         }
12527       else if (unformat (line_input, "group %U",
12528                          unformat_ip6_address, &dst.ip6))
12529         {
12530           grp_set = dst_set = 1;
12531           ipv6_set = 1;
12532         }
12533       else
12534         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12535         ;
12536       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12537         ;
12538       else if (unformat (line_input, "decap-next %U",
12539                          unformat_vxlan_decap_next, &decap_next_index))
12540         ;
12541       else if (unformat (line_input, "vni %d", &vni))
12542         ;
12543       else
12544         {
12545           errmsg ("parse error '%U'", format_unformat_error, line_input);
12546           return -99;
12547         }
12548     }
12549
12550   if (src_set == 0)
12551     {
12552       errmsg ("tunnel src address not specified");
12553       return -99;
12554     }
12555   if (dst_set == 0)
12556     {
12557       errmsg ("tunnel dst address not specified");
12558       return -99;
12559     }
12560
12561   if (grp_set && !ip46_address_is_multicast (&dst))
12562     {
12563       errmsg ("tunnel group address not multicast");
12564       return -99;
12565     }
12566   if (grp_set && mcast_sw_if_index == ~0)
12567     {
12568       errmsg ("tunnel nonexistent multicast device");
12569       return -99;
12570     }
12571   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12572     {
12573       errmsg ("tunnel dst address must be unicast");
12574       return -99;
12575     }
12576
12577
12578   if (ipv4_set && ipv6_set)
12579     {
12580       errmsg ("both IPv4 and IPv6 addresses specified");
12581       return -99;
12582     }
12583
12584   if ((vni == 0) || (vni >> 24))
12585     {
12586       errmsg ("vni not specified or out of range");
12587       return -99;
12588     }
12589
12590   M (VXLAN_ADD_DEL_TUNNEL, mp);
12591
12592   if (ipv6_set)
12593     {
12594       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12595       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12596     }
12597   else
12598     {
12599       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12600       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12601     }
12602
12603   mp->instance = htonl (instance);
12604   mp->encap_vrf_id = ntohl (encap_vrf_id);
12605   mp->decap_next_index = ntohl (decap_next_index);
12606   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12607   mp->vni = ntohl (vni);
12608   mp->is_add = is_add;
12609   mp->is_ipv6 = ipv6_set;
12610
12611   S (mp);
12612   W (ret);
12613   return ret;
12614 }
12615
12616 static void vl_api_vxlan_tunnel_details_t_handler
12617   (vl_api_vxlan_tunnel_details_t * mp)
12618 {
12619   vat_main_t *vam = &vat_main;
12620   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12621   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12622
12623   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12624          ntohl (mp->sw_if_index),
12625          ntohl (mp->instance),
12626          format_ip46_address, &src, IP46_TYPE_ANY,
12627          format_ip46_address, &dst, IP46_TYPE_ANY,
12628          ntohl (mp->encap_vrf_id),
12629          ntohl (mp->decap_next_index), ntohl (mp->vni),
12630          ntohl (mp->mcast_sw_if_index));
12631 }
12632
12633 static void vl_api_vxlan_tunnel_details_t_handler_json
12634   (vl_api_vxlan_tunnel_details_t * mp)
12635 {
12636   vat_main_t *vam = &vat_main;
12637   vat_json_node_t *node = NULL;
12638
12639   if (VAT_JSON_ARRAY != vam->json_tree.type)
12640     {
12641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12642       vat_json_init_array (&vam->json_tree);
12643     }
12644   node = vat_json_array_add (&vam->json_tree);
12645
12646   vat_json_init_object (node);
12647   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12648
12649   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12650
12651   if (mp->is_ipv6)
12652     {
12653       struct in6_addr ip6;
12654
12655       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12656       vat_json_object_add_ip6 (node, "src_address", ip6);
12657       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12658       vat_json_object_add_ip6 (node, "dst_address", ip6);
12659     }
12660   else
12661     {
12662       struct in_addr ip4;
12663
12664       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12665       vat_json_object_add_ip4 (node, "src_address", ip4);
12666       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12667       vat_json_object_add_ip4 (node, "dst_address", ip4);
12668     }
12669   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12670   vat_json_object_add_uint (node, "decap_next_index",
12671                             ntohl (mp->decap_next_index));
12672   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12673   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12674   vat_json_object_add_uint (node, "mcast_sw_if_index",
12675                             ntohl (mp->mcast_sw_if_index));
12676 }
12677
12678 static int
12679 api_vxlan_tunnel_dump (vat_main_t * vam)
12680 {
12681   unformat_input_t *i = vam->input;
12682   vl_api_vxlan_tunnel_dump_t *mp;
12683   vl_api_control_ping_t *mp_ping;
12684   u32 sw_if_index;
12685   u8 sw_if_index_set = 0;
12686   int ret;
12687
12688   /* Parse args required to build the message */
12689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12690     {
12691       if (unformat (i, "sw_if_index %d", &sw_if_index))
12692         sw_if_index_set = 1;
12693       else
12694         break;
12695     }
12696
12697   if (sw_if_index_set == 0)
12698     {
12699       sw_if_index = ~0;
12700     }
12701
12702   if (!vam->json_output)
12703     {
12704       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12705              "sw_if_index", "instance", "src_address", "dst_address",
12706              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12707     }
12708
12709   /* Get list of vxlan-tunnel interfaces */
12710   M (VXLAN_TUNNEL_DUMP, mp);
12711
12712   mp->sw_if_index = htonl (sw_if_index);
12713
12714   S (mp);
12715
12716   /* Use a control ping for synchronization */
12717   MPING (CONTROL_PING, mp_ping);
12718   S (mp_ping);
12719
12720   W (ret);
12721   return ret;
12722 }
12723
12724 static uword unformat_geneve_decap_next
12725   (unformat_input_t * input, va_list * args)
12726 {
12727   u32 *result = va_arg (*args, u32 *);
12728   u32 tmp;
12729
12730   if (unformat (input, "l2"))
12731     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12732   else if (unformat (input, "%d", &tmp))
12733     *result = tmp;
12734   else
12735     return 0;
12736   return 1;
12737 }
12738
12739 static int
12740 api_geneve_add_del_tunnel (vat_main_t * vam)
12741 {
12742   unformat_input_t *line_input = vam->input;
12743   vl_api_geneve_add_del_tunnel_t *mp;
12744   ip46_address_t src, dst;
12745   u8 is_add = 1;
12746   u8 ipv4_set = 0, ipv6_set = 0;
12747   u8 src_set = 0;
12748   u8 dst_set = 0;
12749   u8 grp_set = 0;
12750   u32 mcast_sw_if_index = ~0;
12751   u32 encap_vrf_id = 0;
12752   u32 decap_next_index = ~0;
12753   u32 vni = 0;
12754   int ret;
12755
12756   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12757   clib_memset (&src, 0, sizeof src);
12758   clib_memset (&dst, 0, sizeof dst);
12759
12760   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12761     {
12762       if (unformat (line_input, "del"))
12763         is_add = 0;
12764       else
12765         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12766         {
12767           ipv4_set = 1;
12768           src_set = 1;
12769         }
12770       else
12771         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12772         {
12773           ipv4_set = 1;
12774           dst_set = 1;
12775         }
12776       else
12777         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12778         {
12779           ipv6_set = 1;
12780           src_set = 1;
12781         }
12782       else
12783         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12784         {
12785           ipv6_set = 1;
12786           dst_set = 1;
12787         }
12788       else if (unformat (line_input, "group %U %U",
12789                          unformat_ip4_address, &dst.ip4,
12790                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12791         {
12792           grp_set = dst_set = 1;
12793           ipv4_set = 1;
12794         }
12795       else if (unformat (line_input, "group %U",
12796                          unformat_ip4_address, &dst.ip4))
12797         {
12798           grp_set = dst_set = 1;
12799           ipv4_set = 1;
12800         }
12801       else if (unformat (line_input, "group %U %U",
12802                          unformat_ip6_address, &dst.ip6,
12803                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12804         {
12805           grp_set = dst_set = 1;
12806           ipv6_set = 1;
12807         }
12808       else if (unformat (line_input, "group %U",
12809                          unformat_ip6_address, &dst.ip6))
12810         {
12811           grp_set = dst_set = 1;
12812           ipv6_set = 1;
12813         }
12814       else
12815         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12816         ;
12817       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12818         ;
12819       else if (unformat (line_input, "decap-next %U",
12820                          unformat_geneve_decap_next, &decap_next_index))
12821         ;
12822       else if (unformat (line_input, "vni %d", &vni))
12823         ;
12824       else
12825         {
12826           errmsg ("parse error '%U'", format_unformat_error, line_input);
12827           return -99;
12828         }
12829     }
12830
12831   if (src_set == 0)
12832     {
12833       errmsg ("tunnel src address not specified");
12834       return -99;
12835     }
12836   if (dst_set == 0)
12837     {
12838       errmsg ("tunnel dst address not specified");
12839       return -99;
12840     }
12841
12842   if (grp_set && !ip46_address_is_multicast (&dst))
12843     {
12844       errmsg ("tunnel group address not multicast");
12845       return -99;
12846     }
12847   if (grp_set && mcast_sw_if_index == ~0)
12848     {
12849       errmsg ("tunnel nonexistent multicast device");
12850       return -99;
12851     }
12852   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12853     {
12854       errmsg ("tunnel dst address must be unicast");
12855       return -99;
12856     }
12857
12858
12859   if (ipv4_set && ipv6_set)
12860     {
12861       errmsg ("both IPv4 and IPv6 addresses specified");
12862       return -99;
12863     }
12864
12865   if ((vni == 0) || (vni >> 24))
12866     {
12867       errmsg ("vni not specified or out of range");
12868       return -99;
12869     }
12870
12871   M (GENEVE_ADD_DEL_TUNNEL, mp);
12872
12873   if (ipv6_set)
12874     {
12875       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12876       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12877     }
12878   else
12879     {
12880       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12881       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12882     }
12883   mp->encap_vrf_id = ntohl (encap_vrf_id);
12884   mp->decap_next_index = ntohl (decap_next_index);
12885   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12886   mp->vni = ntohl (vni);
12887   mp->is_add = is_add;
12888   mp->is_ipv6 = ipv6_set;
12889
12890   S (mp);
12891   W (ret);
12892   return ret;
12893 }
12894
12895 static void vl_api_geneve_tunnel_details_t_handler
12896   (vl_api_geneve_tunnel_details_t * mp)
12897 {
12898   vat_main_t *vam = &vat_main;
12899   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12900   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12901
12902   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12903          ntohl (mp->sw_if_index),
12904          format_ip46_address, &src, IP46_TYPE_ANY,
12905          format_ip46_address, &dst, IP46_TYPE_ANY,
12906          ntohl (mp->encap_vrf_id),
12907          ntohl (mp->decap_next_index), ntohl (mp->vni),
12908          ntohl (mp->mcast_sw_if_index));
12909 }
12910
12911 static void vl_api_geneve_tunnel_details_t_handler_json
12912   (vl_api_geneve_tunnel_details_t * mp)
12913 {
12914   vat_main_t *vam = &vat_main;
12915   vat_json_node_t *node = NULL;
12916
12917   if (VAT_JSON_ARRAY != vam->json_tree.type)
12918     {
12919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12920       vat_json_init_array (&vam->json_tree);
12921     }
12922   node = vat_json_array_add (&vam->json_tree);
12923
12924   vat_json_init_object (node);
12925   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12926   if (mp->is_ipv6)
12927     {
12928       struct in6_addr ip6;
12929
12930       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12931       vat_json_object_add_ip6 (node, "src_address", ip6);
12932       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12933       vat_json_object_add_ip6 (node, "dst_address", ip6);
12934     }
12935   else
12936     {
12937       struct in_addr ip4;
12938
12939       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12940       vat_json_object_add_ip4 (node, "src_address", ip4);
12941       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12942       vat_json_object_add_ip4 (node, "dst_address", ip4);
12943     }
12944   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12945   vat_json_object_add_uint (node, "decap_next_index",
12946                             ntohl (mp->decap_next_index));
12947   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12948   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12949   vat_json_object_add_uint (node, "mcast_sw_if_index",
12950                             ntohl (mp->mcast_sw_if_index));
12951 }
12952
12953 static int
12954 api_geneve_tunnel_dump (vat_main_t * vam)
12955 {
12956   unformat_input_t *i = vam->input;
12957   vl_api_geneve_tunnel_dump_t *mp;
12958   vl_api_control_ping_t *mp_ping;
12959   u32 sw_if_index;
12960   u8 sw_if_index_set = 0;
12961   int ret;
12962
12963   /* Parse args required to build the message */
12964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12965     {
12966       if (unformat (i, "sw_if_index %d", &sw_if_index))
12967         sw_if_index_set = 1;
12968       else
12969         break;
12970     }
12971
12972   if (sw_if_index_set == 0)
12973     {
12974       sw_if_index = ~0;
12975     }
12976
12977   if (!vam->json_output)
12978     {
12979       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12980              "sw_if_index", "local_address", "remote_address",
12981              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12982     }
12983
12984   /* Get list of geneve-tunnel interfaces */
12985   M (GENEVE_TUNNEL_DUMP, mp);
12986
12987   mp->sw_if_index = htonl (sw_if_index);
12988
12989   S (mp);
12990
12991   /* Use a control ping for synchronization */
12992   M (CONTROL_PING, mp_ping);
12993   S (mp_ping);
12994
12995   W (ret);
12996   return ret;
12997 }
12998
12999 static int
13000 api_gre_tunnel_add_del (vat_main_t * vam)
13001 {
13002   unformat_input_t *line_input = vam->input;
13003   vl_api_address_t src = { }, dst =
13004   {
13005   };
13006   vl_api_gre_tunnel_add_del_t *mp;
13007   vl_api_gre_tunnel_type_t t_type;
13008   u8 is_add = 1;
13009   u8 src_set = 0;
13010   u8 dst_set = 0;
13011   u32 outer_fib_id = 0;
13012   u32 session_id = 0;
13013   u32 instance = ~0;
13014   int ret;
13015
13016   t_type = GRE_API_TUNNEL_TYPE_L3;
13017
13018   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13019     {
13020       if (unformat (line_input, "del"))
13021         is_add = 0;
13022       else if (unformat (line_input, "instance %d", &instance))
13023         ;
13024       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13025         {
13026           src_set = 1;
13027         }
13028       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13029         {
13030           dst_set = 1;
13031         }
13032       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13033         ;
13034       else if (unformat (line_input, "teb"))
13035         t_type = GRE_API_TUNNEL_TYPE_TEB;
13036       else if (unformat (line_input, "erspan %d", &session_id))
13037         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13038       else
13039         {
13040           errmsg ("parse error '%U'", format_unformat_error, line_input);
13041           return -99;
13042         }
13043     }
13044
13045   if (src_set == 0)
13046     {
13047       errmsg ("tunnel src address not specified");
13048       return -99;
13049     }
13050   if (dst_set == 0)
13051     {
13052       errmsg ("tunnel dst address not specified");
13053       return -99;
13054     }
13055
13056   M (GRE_TUNNEL_ADD_DEL, mp);
13057
13058   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13059   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13060
13061   mp->tunnel.instance = htonl (instance);
13062   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13063   mp->is_add = is_add;
13064   mp->tunnel.session_id = htons ((u16) session_id);
13065   mp->tunnel.type = htonl (t_type);
13066
13067   S (mp);
13068   W (ret);
13069   return ret;
13070 }
13071
13072 static void vl_api_gre_tunnel_details_t_handler
13073   (vl_api_gre_tunnel_details_t * mp)
13074 {
13075   vat_main_t *vam = &vat_main;
13076
13077   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13078          ntohl (mp->tunnel.sw_if_index),
13079          ntohl (mp->tunnel.instance),
13080          format_vl_api_address, &mp->tunnel.src,
13081          format_vl_api_address, &mp->tunnel.dst,
13082          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13083          ntohl (mp->tunnel.session_id));
13084 }
13085
13086 static void vl_api_gre_tunnel_details_t_handler_json
13087   (vl_api_gre_tunnel_details_t * mp)
13088 {
13089   vat_main_t *vam = &vat_main;
13090   vat_json_node_t *node = NULL;
13091
13092   if (VAT_JSON_ARRAY != vam->json_tree.type)
13093     {
13094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13095       vat_json_init_array (&vam->json_tree);
13096     }
13097   node = vat_json_array_add (&vam->json_tree);
13098
13099   vat_json_init_object (node);
13100   vat_json_object_add_uint (node, "sw_if_index",
13101                             ntohl (mp->tunnel.sw_if_index));
13102   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13103
13104   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13105   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13106   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13107   vat_json_object_add_uint (node, "outer_fib_id",
13108                             ntohl (mp->tunnel.outer_fib_id));
13109   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13110 }
13111
13112 static int
13113 api_gre_tunnel_dump (vat_main_t * vam)
13114 {
13115   unformat_input_t *i = vam->input;
13116   vl_api_gre_tunnel_dump_t *mp;
13117   vl_api_control_ping_t *mp_ping;
13118   u32 sw_if_index;
13119   u8 sw_if_index_set = 0;
13120   int ret;
13121
13122   /* Parse args required to build the message */
13123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13124     {
13125       if (unformat (i, "sw_if_index %d", &sw_if_index))
13126         sw_if_index_set = 1;
13127       else
13128         break;
13129     }
13130
13131   if (sw_if_index_set == 0)
13132     {
13133       sw_if_index = ~0;
13134     }
13135
13136   if (!vam->json_output)
13137     {
13138       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13139              "sw_if_index", "instance", "src_address", "dst_address",
13140              "tunnel_type", "outer_fib_id", "session_id");
13141     }
13142
13143   /* Get list of gre-tunnel interfaces */
13144   M (GRE_TUNNEL_DUMP, mp);
13145
13146   mp->sw_if_index = htonl (sw_if_index);
13147
13148   S (mp);
13149
13150   /* Use a control ping for synchronization */
13151   MPING (CONTROL_PING, mp_ping);
13152   S (mp_ping);
13153
13154   W (ret);
13155   return ret;
13156 }
13157
13158 static int
13159 api_l2_fib_clear_table (vat_main_t * vam)
13160 {
13161 //  unformat_input_t * i = vam->input;
13162   vl_api_l2_fib_clear_table_t *mp;
13163   int ret;
13164
13165   M (L2_FIB_CLEAR_TABLE, mp);
13166
13167   S (mp);
13168   W (ret);
13169   return ret;
13170 }
13171
13172 static int
13173 api_l2_interface_efp_filter (vat_main_t * vam)
13174 {
13175   unformat_input_t *i = vam->input;
13176   vl_api_l2_interface_efp_filter_t *mp;
13177   u32 sw_if_index;
13178   u8 enable = 1;
13179   u8 sw_if_index_set = 0;
13180   int ret;
13181
13182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13183     {
13184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13185         sw_if_index_set = 1;
13186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13187         sw_if_index_set = 1;
13188       else if (unformat (i, "enable"))
13189         enable = 1;
13190       else if (unformat (i, "disable"))
13191         enable = 0;
13192       else
13193         {
13194           clib_warning ("parse error '%U'", format_unformat_error, i);
13195           return -99;
13196         }
13197     }
13198
13199   if (sw_if_index_set == 0)
13200     {
13201       errmsg ("missing sw_if_index");
13202       return -99;
13203     }
13204
13205   M (L2_INTERFACE_EFP_FILTER, mp);
13206
13207   mp->sw_if_index = ntohl (sw_if_index);
13208   mp->enable_disable = enable;
13209
13210   S (mp);
13211   W (ret);
13212   return ret;
13213 }
13214
13215 #define foreach_vtr_op                          \
13216 _("disable",  L2_VTR_DISABLED)                  \
13217 _("push-1",  L2_VTR_PUSH_1)                     \
13218 _("push-2",  L2_VTR_PUSH_2)                     \
13219 _("pop-1",  L2_VTR_POP_1)                       \
13220 _("pop-2",  L2_VTR_POP_2)                       \
13221 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13222 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13223 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13224 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13225
13226 static int
13227 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13228 {
13229   unformat_input_t *i = vam->input;
13230   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13231   u32 sw_if_index;
13232   u8 sw_if_index_set = 0;
13233   u8 vtr_op_set = 0;
13234   u32 vtr_op = 0;
13235   u32 push_dot1q = 1;
13236   u32 tag1 = ~0;
13237   u32 tag2 = ~0;
13238   int ret;
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13243         sw_if_index_set = 1;
13244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13245         sw_if_index_set = 1;
13246       else if (unformat (i, "vtr_op %d", &vtr_op))
13247         vtr_op_set = 1;
13248 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13249       foreach_vtr_op
13250 #undef _
13251         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13252         ;
13253       else if (unformat (i, "tag1 %d", &tag1))
13254         ;
13255       else if (unformat (i, "tag2 %d", &tag2))
13256         ;
13257       else
13258         {
13259           clib_warning ("parse error '%U'", format_unformat_error, i);
13260           return -99;
13261         }
13262     }
13263
13264   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13265     {
13266       errmsg ("missing vtr operation or sw_if_index");
13267       return -99;
13268     }
13269
13270   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13271   mp->sw_if_index = ntohl (sw_if_index);
13272   mp->vtr_op = ntohl (vtr_op);
13273   mp->push_dot1q = ntohl (push_dot1q);
13274   mp->tag1 = ntohl (tag1);
13275   mp->tag2 = ntohl (tag2);
13276
13277   S (mp);
13278   W (ret);
13279   return ret;
13280 }
13281
13282 static int
13283 api_create_vhost_user_if (vat_main_t * vam)
13284 {
13285   unformat_input_t *i = vam->input;
13286   vl_api_create_vhost_user_if_t *mp;
13287   u8 *file_name;
13288   u8 is_server = 0;
13289   u8 file_name_set = 0;
13290   u32 custom_dev_instance = ~0;
13291   u8 hwaddr[6];
13292   u8 use_custom_mac = 0;
13293   u8 disable_mrg_rxbuf = 0;
13294   u8 disable_indirect_desc = 0;
13295   u8 *tag = 0;
13296   int ret;
13297
13298   /* Shut up coverity */
13299   clib_memset (hwaddr, 0, sizeof (hwaddr));
13300
13301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13302     {
13303       if (unformat (i, "socket %s", &file_name))
13304         {
13305           file_name_set = 1;
13306         }
13307       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13308         ;
13309       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13310         use_custom_mac = 1;
13311       else if (unformat (i, "server"))
13312         is_server = 1;
13313       else if (unformat (i, "disable_mrg_rxbuf"))
13314         disable_mrg_rxbuf = 1;
13315       else if (unformat (i, "disable_indirect_desc"))
13316         disable_indirect_desc = 1;
13317       else if (unformat (i, "tag %s", &tag))
13318         ;
13319       else
13320         break;
13321     }
13322
13323   if (file_name_set == 0)
13324     {
13325       errmsg ("missing socket file name");
13326       return -99;
13327     }
13328
13329   if (vec_len (file_name) > 255)
13330     {
13331       errmsg ("socket file name too long");
13332       return -99;
13333     }
13334   vec_add1 (file_name, 0);
13335
13336   M (CREATE_VHOST_USER_IF, mp);
13337
13338   mp->is_server = is_server;
13339   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13340   mp->disable_indirect_desc = disable_indirect_desc;
13341   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13342   vec_free (file_name);
13343   if (custom_dev_instance != ~0)
13344     {
13345       mp->renumber = 1;
13346       mp->custom_dev_instance = ntohl (custom_dev_instance);
13347     }
13348
13349   mp->use_custom_mac = use_custom_mac;
13350   clib_memcpy (mp->mac_address, hwaddr, 6);
13351   if (tag)
13352     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13353   vec_free (tag);
13354
13355   S (mp);
13356   W (ret);
13357   return ret;
13358 }
13359
13360 static int
13361 api_modify_vhost_user_if (vat_main_t * vam)
13362 {
13363   unformat_input_t *i = vam->input;
13364   vl_api_modify_vhost_user_if_t *mp;
13365   u8 *file_name;
13366   u8 is_server = 0;
13367   u8 file_name_set = 0;
13368   u32 custom_dev_instance = ~0;
13369   u8 sw_if_index_set = 0;
13370   u32 sw_if_index = (u32) ~ 0;
13371   int ret;
13372
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13376         sw_if_index_set = 1;
13377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13378         sw_if_index_set = 1;
13379       else if (unformat (i, "socket %s", &file_name))
13380         {
13381           file_name_set = 1;
13382         }
13383       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13384         ;
13385       else if (unformat (i, "server"))
13386         is_server = 1;
13387       else
13388         break;
13389     }
13390
13391   if (sw_if_index_set == 0)
13392     {
13393       errmsg ("missing sw_if_index or interface name");
13394       return -99;
13395     }
13396
13397   if (file_name_set == 0)
13398     {
13399       errmsg ("missing socket file name");
13400       return -99;
13401     }
13402
13403   if (vec_len (file_name) > 255)
13404     {
13405       errmsg ("socket file name too long");
13406       return -99;
13407     }
13408   vec_add1 (file_name, 0);
13409
13410   M (MODIFY_VHOST_USER_IF, mp);
13411
13412   mp->sw_if_index = ntohl (sw_if_index);
13413   mp->is_server = is_server;
13414   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13415   vec_free (file_name);
13416   if (custom_dev_instance != ~0)
13417     {
13418       mp->renumber = 1;
13419       mp->custom_dev_instance = ntohl (custom_dev_instance);
13420     }
13421
13422   S (mp);
13423   W (ret);
13424   return ret;
13425 }
13426
13427 static int
13428 api_delete_vhost_user_if (vat_main_t * vam)
13429 {
13430   unformat_input_t *i = vam->input;
13431   vl_api_delete_vhost_user_if_t *mp;
13432   u32 sw_if_index = ~0;
13433   u8 sw_if_index_set = 0;
13434   int ret;
13435
13436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13437     {
13438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13439         sw_if_index_set = 1;
13440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13441         sw_if_index_set = 1;
13442       else
13443         break;
13444     }
13445
13446   if (sw_if_index_set == 0)
13447     {
13448       errmsg ("missing sw_if_index or interface name");
13449       return -99;
13450     }
13451
13452
13453   M (DELETE_VHOST_USER_IF, mp);
13454
13455   mp->sw_if_index = ntohl (sw_if_index);
13456
13457   S (mp);
13458   W (ret);
13459   return ret;
13460 }
13461
13462 static void vl_api_sw_interface_vhost_user_details_t_handler
13463   (vl_api_sw_interface_vhost_user_details_t * mp)
13464 {
13465   vat_main_t *vam = &vat_main;
13466
13467   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13468          (char *) mp->interface_name,
13469          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13470          clib_net_to_host_u64 (mp->features), mp->is_server,
13471          ntohl (mp->num_regions), (char *) mp->sock_filename);
13472   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13473 }
13474
13475 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13476   (vl_api_sw_interface_vhost_user_details_t * mp)
13477 {
13478   vat_main_t *vam = &vat_main;
13479   vat_json_node_t *node = NULL;
13480
13481   if (VAT_JSON_ARRAY != vam->json_tree.type)
13482     {
13483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13484       vat_json_init_array (&vam->json_tree);
13485     }
13486   node = vat_json_array_add (&vam->json_tree);
13487
13488   vat_json_init_object (node);
13489   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13490   vat_json_object_add_string_copy (node, "interface_name",
13491                                    mp->interface_name);
13492   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13493                             ntohl (mp->virtio_net_hdr_sz));
13494   vat_json_object_add_uint (node, "features",
13495                             clib_net_to_host_u64 (mp->features));
13496   vat_json_object_add_uint (node, "is_server", mp->is_server);
13497   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13498   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13499   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13500 }
13501
13502 static int
13503 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13504 {
13505   vl_api_sw_interface_vhost_user_dump_t *mp;
13506   vl_api_control_ping_t *mp_ping;
13507   int ret;
13508   print (vam->ofp,
13509          "Interface name            idx hdr_sz features server regions filename");
13510
13511   /* Get list of vhost-user interfaces */
13512   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13513   S (mp);
13514
13515   /* Use a control ping for synchronization */
13516   MPING (CONTROL_PING, mp_ping);
13517   S (mp_ping);
13518
13519   W (ret);
13520   return ret;
13521 }
13522
13523 static int
13524 api_show_version (vat_main_t * vam)
13525 {
13526   vl_api_show_version_t *mp;
13527   int ret;
13528
13529   M (SHOW_VERSION, mp);
13530
13531   S (mp);
13532   W (ret);
13533   return ret;
13534 }
13535
13536
13537 static int
13538 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13539 {
13540   unformat_input_t *line_input = vam->input;
13541   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13542   ip4_address_t local4, remote4;
13543   ip6_address_t local6, remote6;
13544   u8 is_add = 1;
13545   u8 ipv4_set = 0, ipv6_set = 0;
13546   u8 local_set = 0;
13547   u8 remote_set = 0;
13548   u8 grp_set = 0;
13549   u32 mcast_sw_if_index = ~0;
13550   u32 encap_vrf_id = 0;
13551   u32 decap_vrf_id = 0;
13552   u8 protocol = ~0;
13553   u32 vni;
13554   u8 vni_set = 0;
13555   int ret;
13556
13557   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13558   clib_memset (&local4, 0, sizeof local4);
13559   clib_memset (&remote4, 0, sizeof remote4);
13560   clib_memset (&local6, 0, sizeof local6);
13561   clib_memset (&remote6, 0, sizeof remote6);
13562
13563   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13564     {
13565       if (unformat (line_input, "del"))
13566         is_add = 0;
13567       else if (unformat (line_input, "local %U",
13568                          unformat_ip4_address, &local4))
13569         {
13570           local_set = 1;
13571           ipv4_set = 1;
13572         }
13573       else if (unformat (line_input, "remote %U",
13574                          unformat_ip4_address, &remote4))
13575         {
13576           remote_set = 1;
13577           ipv4_set = 1;
13578         }
13579       else if (unformat (line_input, "local %U",
13580                          unformat_ip6_address, &local6))
13581         {
13582           local_set = 1;
13583           ipv6_set = 1;
13584         }
13585       else if (unformat (line_input, "remote %U",
13586                          unformat_ip6_address, &remote6))
13587         {
13588           remote_set = 1;
13589           ipv6_set = 1;
13590         }
13591       else if (unformat (line_input, "group %U %U",
13592                          unformat_ip4_address, &remote4,
13593                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13594         {
13595           grp_set = remote_set = 1;
13596           ipv4_set = 1;
13597         }
13598       else if (unformat (line_input, "group %U",
13599                          unformat_ip4_address, &remote4))
13600         {
13601           grp_set = remote_set = 1;
13602           ipv4_set = 1;
13603         }
13604       else if (unformat (line_input, "group %U %U",
13605                          unformat_ip6_address, &remote6,
13606                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13607         {
13608           grp_set = remote_set = 1;
13609           ipv6_set = 1;
13610         }
13611       else if (unformat (line_input, "group %U",
13612                          unformat_ip6_address, &remote6))
13613         {
13614           grp_set = remote_set = 1;
13615           ipv6_set = 1;
13616         }
13617       else
13618         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13619         ;
13620       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13621         ;
13622       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13623         ;
13624       else if (unformat (line_input, "vni %d", &vni))
13625         vni_set = 1;
13626       else if (unformat (line_input, "next-ip4"))
13627         protocol = 1;
13628       else if (unformat (line_input, "next-ip6"))
13629         protocol = 2;
13630       else if (unformat (line_input, "next-ethernet"))
13631         protocol = 3;
13632       else if (unformat (line_input, "next-nsh"))
13633         protocol = 4;
13634       else
13635         {
13636           errmsg ("parse error '%U'", format_unformat_error, line_input);
13637           return -99;
13638         }
13639     }
13640
13641   if (local_set == 0)
13642     {
13643       errmsg ("tunnel local address not specified");
13644       return -99;
13645     }
13646   if (remote_set == 0)
13647     {
13648       errmsg ("tunnel remote address not specified");
13649       return -99;
13650     }
13651   if (grp_set && mcast_sw_if_index == ~0)
13652     {
13653       errmsg ("tunnel nonexistent multicast device");
13654       return -99;
13655     }
13656   if (ipv4_set && ipv6_set)
13657     {
13658       errmsg ("both IPv4 and IPv6 addresses specified");
13659       return -99;
13660     }
13661
13662   if (vni_set == 0)
13663     {
13664       errmsg ("vni not specified");
13665       return -99;
13666     }
13667
13668   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13669
13670
13671   if (ipv6_set)
13672     {
13673       clib_memcpy (&mp->local, &local6, sizeof (local6));
13674       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13675     }
13676   else
13677     {
13678       clib_memcpy (&mp->local, &local4, sizeof (local4));
13679       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13680     }
13681
13682   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13683   mp->encap_vrf_id = ntohl (encap_vrf_id);
13684   mp->decap_vrf_id = ntohl (decap_vrf_id);
13685   mp->protocol = protocol;
13686   mp->vni = ntohl (vni);
13687   mp->is_add = is_add;
13688   mp->is_ipv6 = ipv6_set;
13689
13690   S (mp);
13691   W (ret);
13692   return ret;
13693 }
13694
13695 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13696   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13697 {
13698   vat_main_t *vam = &vat_main;
13699   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13700   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13701
13702   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13703          ntohl (mp->sw_if_index),
13704          format_ip46_address, &local, IP46_TYPE_ANY,
13705          format_ip46_address, &remote, IP46_TYPE_ANY,
13706          ntohl (mp->vni), mp->protocol,
13707          ntohl (mp->mcast_sw_if_index),
13708          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13709 }
13710
13711
13712 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13713   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13714 {
13715   vat_main_t *vam = &vat_main;
13716   vat_json_node_t *node = NULL;
13717   struct in_addr ip4;
13718   struct in6_addr ip6;
13719
13720   if (VAT_JSON_ARRAY != vam->json_tree.type)
13721     {
13722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13723       vat_json_init_array (&vam->json_tree);
13724     }
13725   node = vat_json_array_add (&vam->json_tree);
13726
13727   vat_json_init_object (node);
13728   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13729   if (mp->is_ipv6)
13730     {
13731       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13732       vat_json_object_add_ip6 (node, "local", ip6);
13733       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13734       vat_json_object_add_ip6 (node, "remote", ip6);
13735     }
13736   else
13737     {
13738       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13739       vat_json_object_add_ip4 (node, "local", ip4);
13740       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13741       vat_json_object_add_ip4 (node, "remote", ip4);
13742     }
13743   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13744   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13745   vat_json_object_add_uint (node, "mcast_sw_if_index",
13746                             ntohl (mp->mcast_sw_if_index));
13747   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13748   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13749   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13750 }
13751
13752 static int
13753 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13754 {
13755   unformat_input_t *i = vam->input;
13756   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13757   vl_api_control_ping_t *mp_ping;
13758   u32 sw_if_index;
13759   u8 sw_if_index_set = 0;
13760   int ret;
13761
13762   /* Parse args required to build the message */
13763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13764     {
13765       if (unformat (i, "sw_if_index %d", &sw_if_index))
13766         sw_if_index_set = 1;
13767       else
13768         break;
13769     }
13770
13771   if (sw_if_index_set == 0)
13772     {
13773       sw_if_index = ~0;
13774     }
13775
13776   if (!vam->json_output)
13777     {
13778       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13779              "sw_if_index", "local", "remote", "vni",
13780              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13781     }
13782
13783   /* Get list of vxlan-tunnel interfaces */
13784   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13785
13786   mp->sw_if_index = htonl (sw_if_index);
13787
13788   S (mp);
13789
13790   /* Use a control ping for synchronization */
13791   MPING (CONTROL_PING, mp_ping);
13792   S (mp_ping);
13793
13794   W (ret);
13795   return ret;
13796 }
13797
13798 static void vl_api_l2_fib_table_details_t_handler
13799   (vl_api_l2_fib_table_details_t * mp)
13800 {
13801   vat_main_t *vam = &vat_main;
13802
13803   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13804          "       %d       %d     %d",
13805          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13806          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13807          mp->bvi_mac);
13808 }
13809
13810 static void vl_api_l2_fib_table_details_t_handler_json
13811   (vl_api_l2_fib_table_details_t * mp)
13812 {
13813   vat_main_t *vam = &vat_main;
13814   vat_json_node_t *node = NULL;
13815
13816   if (VAT_JSON_ARRAY != vam->json_tree.type)
13817     {
13818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13819       vat_json_init_array (&vam->json_tree);
13820     }
13821   node = vat_json_array_add (&vam->json_tree);
13822
13823   vat_json_init_object (node);
13824   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13825   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13826   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13827   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13828   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13829   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13830 }
13831
13832 static int
13833 api_l2_fib_table_dump (vat_main_t * vam)
13834 {
13835   unformat_input_t *i = vam->input;
13836   vl_api_l2_fib_table_dump_t *mp;
13837   vl_api_control_ping_t *mp_ping;
13838   u32 bd_id;
13839   u8 bd_id_set = 0;
13840   int ret;
13841
13842   /* Parse args required to build the message */
13843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13844     {
13845       if (unformat (i, "bd_id %d", &bd_id))
13846         bd_id_set = 1;
13847       else
13848         break;
13849     }
13850
13851   if (bd_id_set == 0)
13852     {
13853       errmsg ("missing bridge domain");
13854       return -99;
13855     }
13856
13857   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13858
13859   /* Get list of l2 fib entries */
13860   M (L2_FIB_TABLE_DUMP, mp);
13861
13862   mp->bd_id = ntohl (bd_id);
13863   S (mp);
13864
13865   /* Use a control ping for synchronization */
13866   MPING (CONTROL_PING, mp_ping);
13867   S (mp_ping);
13868
13869   W (ret);
13870   return ret;
13871 }
13872
13873
13874 static int
13875 api_interface_name_renumber (vat_main_t * vam)
13876 {
13877   unformat_input_t *line_input = vam->input;
13878   vl_api_interface_name_renumber_t *mp;
13879   u32 sw_if_index = ~0;
13880   u32 new_show_dev_instance = ~0;
13881   int ret;
13882
13883   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13886                     &sw_if_index))
13887         ;
13888       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13889         ;
13890       else if (unformat (line_input, "new_show_dev_instance %d",
13891                          &new_show_dev_instance))
13892         ;
13893       else
13894         break;
13895     }
13896
13897   if (sw_if_index == ~0)
13898     {
13899       errmsg ("missing interface name or sw_if_index");
13900       return -99;
13901     }
13902
13903   if (new_show_dev_instance == ~0)
13904     {
13905       errmsg ("missing new_show_dev_instance");
13906       return -99;
13907     }
13908
13909   M (INTERFACE_NAME_RENUMBER, mp);
13910
13911   mp->sw_if_index = ntohl (sw_if_index);
13912   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13913
13914   S (mp);
13915   W (ret);
13916   return ret;
13917 }
13918
13919 static int
13920 api_ip_probe_neighbor (vat_main_t * vam)
13921 {
13922   unformat_input_t *i = vam->input;
13923   vl_api_ip_probe_neighbor_t *mp;
13924   vl_api_address_t dst_adr = { };
13925   u8 int_set = 0;
13926   u8 adr_set = 0;
13927   u32 sw_if_index;
13928   int ret;
13929
13930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13931     {
13932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13933         int_set = 1;
13934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13935         int_set = 1;
13936       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13937         adr_set = 1;
13938       else
13939         break;
13940     }
13941
13942   if (int_set == 0)
13943     {
13944       errmsg ("missing interface");
13945       return -99;
13946     }
13947
13948   if (adr_set == 0)
13949     {
13950       errmsg ("missing addresses");
13951       return -99;
13952     }
13953
13954   M (IP_PROBE_NEIGHBOR, mp);
13955
13956   mp->sw_if_index = ntohl (sw_if_index);
13957   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13958
13959   S (mp);
13960   W (ret);
13961   return ret;
13962 }
13963
13964 static int
13965 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13966 {
13967   unformat_input_t *i = vam->input;
13968   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13969   u8 mode = IP_SCAN_V46_NEIGHBORS;
13970   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13971   int ret;
13972
13973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13974     {
13975       if (unformat (i, "ip4"))
13976         mode = IP_SCAN_V4_NEIGHBORS;
13977       else if (unformat (i, "ip6"))
13978         mode = IP_SCAN_V6_NEIGHBORS;
13979       if (unformat (i, "both"))
13980         mode = IP_SCAN_V46_NEIGHBORS;
13981       else if (unformat (i, "disable"))
13982         mode = IP_SCAN_DISABLED;
13983       else if (unformat (i, "interval %d", &interval))
13984         ;
13985       else if (unformat (i, "max-time %d", &time))
13986         ;
13987       else if (unformat (i, "max-update %d", &update))
13988         ;
13989       else if (unformat (i, "delay %d", &delay))
13990         ;
13991       else if (unformat (i, "stale %d", &stale))
13992         ;
13993       else
13994         break;
13995     }
13996
13997   if (interval > 255)
13998     {
13999       errmsg ("interval cannot exceed 255 minutes.");
14000       return -99;
14001     }
14002   if (time > 255)
14003     {
14004       errmsg ("max-time cannot exceed 255 usec.");
14005       return -99;
14006     }
14007   if (update > 255)
14008     {
14009       errmsg ("max-update cannot exceed 255.");
14010       return -99;
14011     }
14012   if (delay > 255)
14013     {
14014       errmsg ("delay cannot exceed 255 msec.");
14015       return -99;
14016     }
14017   if (stale > 255)
14018     {
14019       errmsg ("stale cannot exceed 255 minutes.");
14020       return -99;
14021     }
14022
14023   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14024   mp->mode = mode;
14025   mp->scan_interval = interval;
14026   mp->max_proc_time = time;
14027   mp->max_update = update;
14028   mp->scan_int_delay = delay;
14029   mp->stale_threshold = stale;
14030
14031   S (mp);
14032   W (ret);
14033   return ret;
14034 }
14035
14036 static int
14037 api_want_ip4_arp_events (vat_main_t * vam)
14038 {
14039   unformat_input_t *line_input = vam->input;
14040   vl_api_want_ip4_arp_events_t *mp;
14041   ip4_address_t address;
14042   int address_set = 0;
14043   u32 enable_disable = 1;
14044   int ret;
14045
14046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14047     {
14048       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14049         address_set = 1;
14050       else if (unformat (line_input, "del"))
14051         enable_disable = 0;
14052       else
14053         break;
14054     }
14055
14056   if (address_set == 0)
14057     {
14058       errmsg ("missing addresses");
14059       return -99;
14060     }
14061
14062   M (WANT_IP4_ARP_EVENTS, mp);
14063   mp->enable_disable = enable_disable;
14064   mp->pid = htonl (getpid ());
14065   clib_memcpy (mp->ip, &address, sizeof (address));
14066
14067   S (mp);
14068   W (ret);
14069   return ret;
14070 }
14071
14072 static int
14073 api_want_ip6_nd_events (vat_main_t * vam)
14074 {
14075   unformat_input_t *line_input = vam->input;
14076   vl_api_want_ip6_nd_events_t *mp;
14077   vl_api_ip6_address_t address;
14078   int address_set = 0;
14079   u32 enable_disable = 1;
14080   int ret;
14081
14082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14083     {
14084       if (unformat
14085           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14086         address_set = 1;
14087       else if (unformat (line_input, "del"))
14088         enable_disable = 0;
14089       else
14090         break;
14091     }
14092
14093   if (address_set == 0)
14094     {
14095       errmsg ("missing addresses");
14096       return -99;
14097     }
14098
14099   M (WANT_IP6_ND_EVENTS, mp);
14100   mp->enable_disable = enable_disable;
14101   mp->pid = htonl (getpid ());
14102   clib_memcpy (&mp->ip, &address, sizeof (address));
14103
14104   S (mp);
14105   W (ret);
14106   return ret;
14107 }
14108
14109 static int
14110 api_want_l2_macs_events (vat_main_t * vam)
14111 {
14112   unformat_input_t *line_input = vam->input;
14113   vl_api_want_l2_macs_events_t *mp;
14114   u8 enable_disable = 1;
14115   u32 scan_delay = 0;
14116   u32 max_macs_in_event = 0;
14117   u32 learn_limit = 0;
14118   int ret;
14119
14120   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14121     {
14122       if (unformat (line_input, "learn-limit %d", &learn_limit))
14123         ;
14124       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14125         ;
14126       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14127         ;
14128       else if (unformat (line_input, "disable"))
14129         enable_disable = 0;
14130       else
14131         break;
14132     }
14133
14134   M (WANT_L2_MACS_EVENTS, mp);
14135   mp->enable_disable = enable_disable;
14136   mp->pid = htonl (getpid ());
14137   mp->learn_limit = htonl (learn_limit);
14138   mp->scan_delay = (u8) scan_delay;
14139   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14140   S (mp);
14141   W (ret);
14142   return ret;
14143 }
14144
14145 static int
14146 api_input_acl_set_interface (vat_main_t * vam)
14147 {
14148   unformat_input_t *i = vam->input;
14149   vl_api_input_acl_set_interface_t *mp;
14150   u32 sw_if_index;
14151   int sw_if_index_set;
14152   u32 ip4_table_index = ~0;
14153   u32 ip6_table_index = ~0;
14154   u32 l2_table_index = ~0;
14155   u8 is_add = 1;
14156   int ret;
14157
14158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14161         sw_if_index_set = 1;
14162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14163         sw_if_index_set = 1;
14164       else if (unformat (i, "del"))
14165         is_add = 0;
14166       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14167         ;
14168       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14169         ;
14170       else if (unformat (i, "l2-table %d", &l2_table_index))
14171         ;
14172       else
14173         {
14174           clib_warning ("parse error '%U'", format_unformat_error, i);
14175           return -99;
14176         }
14177     }
14178
14179   if (sw_if_index_set == 0)
14180     {
14181       errmsg ("missing interface name or sw_if_index");
14182       return -99;
14183     }
14184
14185   M (INPUT_ACL_SET_INTERFACE, mp);
14186
14187   mp->sw_if_index = ntohl (sw_if_index);
14188   mp->ip4_table_index = ntohl (ip4_table_index);
14189   mp->ip6_table_index = ntohl (ip6_table_index);
14190   mp->l2_table_index = ntohl (l2_table_index);
14191   mp->is_add = is_add;
14192
14193   S (mp);
14194   W (ret);
14195   return ret;
14196 }
14197
14198 static int
14199 api_output_acl_set_interface (vat_main_t * vam)
14200 {
14201   unformat_input_t *i = vam->input;
14202   vl_api_output_acl_set_interface_t *mp;
14203   u32 sw_if_index;
14204   int sw_if_index_set;
14205   u32 ip4_table_index = ~0;
14206   u32 ip6_table_index = ~0;
14207   u32 l2_table_index = ~0;
14208   u8 is_add = 1;
14209   int ret;
14210
14211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14214         sw_if_index_set = 1;
14215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14216         sw_if_index_set = 1;
14217       else if (unformat (i, "del"))
14218         is_add = 0;
14219       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14220         ;
14221       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14222         ;
14223       else if (unformat (i, "l2-table %d", &l2_table_index))
14224         ;
14225       else
14226         {
14227           clib_warning ("parse error '%U'", format_unformat_error, i);
14228           return -99;
14229         }
14230     }
14231
14232   if (sw_if_index_set == 0)
14233     {
14234       errmsg ("missing interface name or sw_if_index");
14235       return -99;
14236     }
14237
14238   M (OUTPUT_ACL_SET_INTERFACE, mp);
14239
14240   mp->sw_if_index = ntohl (sw_if_index);
14241   mp->ip4_table_index = ntohl (ip4_table_index);
14242   mp->ip6_table_index = ntohl (ip6_table_index);
14243   mp->l2_table_index = ntohl (l2_table_index);
14244   mp->is_add = is_add;
14245
14246   S (mp);
14247   W (ret);
14248   return ret;
14249 }
14250
14251 static int
14252 api_ip_address_dump (vat_main_t * vam)
14253 {
14254   unformat_input_t *i = vam->input;
14255   vl_api_ip_address_dump_t *mp;
14256   vl_api_control_ping_t *mp_ping;
14257   u32 sw_if_index = ~0;
14258   u8 sw_if_index_set = 0;
14259   u8 ipv4_set = 0;
14260   u8 ipv6_set = 0;
14261   int ret;
14262
14263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14264     {
14265       if (unformat (i, "sw_if_index %d", &sw_if_index))
14266         sw_if_index_set = 1;
14267       else
14268         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14269         sw_if_index_set = 1;
14270       else if (unformat (i, "ipv4"))
14271         ipv4_set = 1;
14272       else if (unformat (i, "ipv6"))
14273         ipv6_set = 1;
14274       else
14275         break;
14276     }
14277
14278   if (ipv4_set && ipv6_set)
14279     {
14280       errmsg ("ipv4 and ipv6 flags cannot be both set");
14281       return -99;
14282     }
14283
14284   if ((!ipv4_set) && (!ipv6_set))
14285     {
14286       errmsg ("no ipv4 nor ipv6 flag set");
14287       return -99;
14288     }
14289
14290   if (sw_if_index_set == 0)
14291     {
14292       errmsg ("missing interface name or sw_if_index");
14293       return -99;
14294     }
14295
14296   vam->current_sw_if_index = sw_if_index;
14297   vam->is_ipv6 = ipv6_set;
14298
14299   M (IP_ADDRESS_DUMP, mp);
14300   mp->sw_if_index = ntohl (sw_if_index);
14301   mp->is_ipv6 = ipv6_set;
14302   S (mp);
14303
14304   /* Use a control ping for synchronization */
14305   MPING (CONTROL_PING, mp_ping);
14306   S (mp_ping);
14307
14308   W (ret);
14309   return ret;
14310 }
14311
14312 static int
14313 api_ip_dump (vat_main_t * vam)
14314 {
14315   vl_api_ip_dump_t *mp;
14316   vl_api_control_ping_t *mp_ping;
14317   unformat_input_t *in = vam->input;
14318   int ipv4_set = 0;
14319   int ipv6_set = 0;
14320   int is_ipv6;
14321   int i;
14322   int ret;
14323
14324   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14325     {
14326       if (unformat (in, "ipv4"))
14327         ipv4_set = 1;
14328       else if (unformat (in, "ipv6"))
14329         ipv6_set = 1;
14330       else
14331         break;
14332     }
14333
14334   if (ipv4_set && ipv6_set)
14335     {
14336       errmsg ("ipv4 and ipv6 flags cannot be both set");
14337       return -99;
14338     }
14339
14340   if ((!ipv4_set) && (!ipv6_set))
14341     {
14342       errmsg ("no ipv4 nor ipv6 flag set");
14343       return -99;
14344     }
14345
14346   is_ipv6 = ipv6_set;
14347   vam->is_ipv6 = is_ipv6;
14348
14349   /* free old data */
14350   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14351     {
14352       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14353     }
14354   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14355
14356   M (IP_DUMP, mp);
14357   mp->is_ipv6 = ipv6_set;
14358   S (mp);
14359
14360   /* Use a control ping for synchronization */
14361   MPING (CONTROL_PING, mp_ping);
14362   S (mp_ping);
14363
14364   W (ret);
14365   return ret;
14366 }
14367
14368 static int
14369 api_ipsec_spd_add_del (vat_main_t * vam)
14370 {
14371   unformat_input_t *i = vam->input;
14372   vl_api_ipsec_spd_add_del_t *mp;
14373   u32 spd_id = ~0;
14374   u8 is_add = 1;
14375   int ret;
14376
14377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14378     {
14379       if (unformat (i, "spd_id %d", &spd_id))
14380         ;
14381       else if (unformat (i, "del"))
14382         is_add = 0;
14383       else
14384         {
14385           clib_warning ("parse error '%U'", format_unformat_error, i);
14386           return -99;
14387         }
14388     }
14389   if (spd_id == ~0)
14390     {
14391       errmsg ("spd_id must be set");
14392       return -99;
14393     }
14394
14395   M (IPSEC_SPD_ADD_DEL, mp);
14396
14397   mp->spd_id = ntohl (spd_id);
14398   mp->is_add = is_add;
14399
14400   S (mp);
14401   W (ret);
14402   return ret;
14403 }
14404
14405 static int
14406 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14407 {
14408   unformat_input_t *i = vam->input;
14409   vl_api_ipsec_interface_add_del_spd_t *mp;
14410   u32 sw_if_index;
14411   u8 sw_if_index_set = 0;
14412   u32 spd_id = (u32) ~ 0;
14413   u8 is_add = 1;
14414   int ret;
14415
14416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14417     {
14418       if (unformat (i, "del"))
14419         is_add = 0;
14420       else if (unformat (i, "spd_id %d", &spd_id))
14421         ;
14422       else
14423         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14424         sw_if_index_set = 1;
14425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14426         sw_if_index_set = 1;
14427       else
14428         {
14429           clib_warning ("parse error '%U'", format_unformat_error, i);
14430           return -99;
14431         }
14432
14433     }
14434
14435   if (spd_id == (u32) ~ 0)
14436     {
14437       errmsg ("spd_id must be set");
14438       return -99;
14439     }
14440
14441   if (sw_if_index_set == 0)
14442     {
14443       errmsg ("missing interface name or sw_if_index");
14444       return -99;
14445     }
14446
14447   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14448
14449   mp->spd_id = ntohl (spd_id);
14450   mp->sw_if_index = ntohl (sw_if_index);
14451   mp->is_add = is_add;
14452
14453   S (mp);
14454   W (ret);
14455   return ret;
14456 }
14457
14458 static int
14459 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14460 {
14461   unformat_input_t *i = vam->input;
14462   vl_api_ipsec_spd_entry_add_del_t *mp;
14463   u8 is_add = 1, is_outbound = 0;
14464   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14465   i32 priority = 0;
14466   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14467   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14468   vl_api_address_t laddr_start = { }, laddr_stop =
14469   {
14470   }, raddr_start =
14471   {
14472   }, raddr_stop =
14473   {
14474   };
14475   int ret;
14476
14477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (i, "del"))
14480         is_add = 0;
14481       if (unformat (i, "outbound"))
14482         is_outbound = 1;
14483       if (unformat (i, "inbound"))
14484         is_outbound = 0;
14485       else if (unformat (i, "spd_id %d", &spd_id))
14486         ;
14487       else if (unformat (i, "sa_id %d", &sa_id))
14488         ;
14489       else if (unformat (i, "priority %d", &priority))
14490         ;
14491       else if (unformat (i, "protocol %d", &protocol))
14492         ;
14493       else if (unformat (i, "lport_start %d", &lport_start))
14494         ;
14495       else if (unformat (i, "lport_stop %d", &lport_stop))
14496         ;
14497       else if (unformat (i, "rport_start %d", &rport_start))
14498         ;
14499       else if (unformat (i, "rport_stop %d", &rport_stop))
14500         ;
14501       else if (unformat (i, "laddr_start %U",
14502                          unformat_vl_api_address, &laddr_start))
14503         ;
14504       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14505                          &laddr_stop))
14506         ;
14507       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14508                          &raddr_start))
14509         ;
14510       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14511                          &raddr_stop))
14512         ;
14513       else
14514         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14515         {
14516           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14517             {
14518               clib_warning ("unsupported action: 'resolve'");
14519               return -99;
14520             }
14521         }
14522       else
14523         {
14524           clib_warning ("parse error '%U'", format_unformat_error, i);
14525           return -99;
14526         }
14527
14528     }
14529
14530   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14531
14532   mp->is_add = is_add;
14533
14534   mp->entry.spd_id = ntohl (spd_id);
14535   mp->entry.priority = ntohl (priority);
14536   mp->entry.is_outbound = is_outbound;
14537
14538   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14539                sizeof (vl_api_address_t));
14540   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14541                sizeof (vl_api_address_t));
14542   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14543                sizeof (vl_api_address_t));
14544   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14545                sizeof (vl_api_address_t));
14546
14547   mp->entry.protocol = (u8) protocol;
14548   mp->entry.local_port_start = ntohs ((u16) lport_start);
14549   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14550   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14551   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14552   mp->entry.policy = (u8) policy;
14553   mp->entry.sa_id = ntohl (sa_id);
14554
14555   S (mp);
14556   W (ret);
14557   return ret;
14558 }
14559
14560 static int
14561 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14562 {
14563   unformat_input_t *i = vam->input;
14564   vl_api_ipsec_sad_entry_add_del_t *mp;
14565   u32 sad_id = 0, spi = 0;
14566   u8 *ck = 0, *ik = 0;
14567   u8 is_add = 1;
14568
14569   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14570   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14571   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14572   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14573   vl_api_address_t tun_src, tun_dst;
14574   int ret;
14575
14576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14577     {
14578       if (unformat (i, "del"))
14579         is_add = 0;
14580       else if (unformat (i, "sad_id %d", &sad_id))
14581         ;
14582       else if (unformat (i, "spi %d", &spi))
14583         ;
14584       else if (unformat (i, "esp"))
14585         protocol = IPSEC_API_PROTO_ESP;
14586       else
14587         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14588         {
14589           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14590           if (ADDRESS_IP6 == tun_src.af)
14591             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14592         }
14593       else
14594         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14595         {
14596           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14597           if (ADDRESS_IP6 == tun_src.af)
14598             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14599         }
14600       else
14601         if (unformat (i, "crypto_alg %U",
14602                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14603         ;
14604       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14605         ;
14606       else if (unformat (i, "integ_alg %U",
14607                          unformat_ipsec_api_integ_alg, &integ_alg))
14608         ;
14609       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14610         ;
14611       else
14612         {
14613           clib_warning ("parse error '%U'", format_unformat_error, i);
14614           return -99;
14615         }
14616
14617     }
14618
14619   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14620
14621   mp->is_add = is_add;
14622   mp->entry.sad_id = ntohl (sad_id);
14623   mp->entry.protocol = protocol;
14624   mp->entry.spi = ntohl (spi);
14625   mp->entry.flags = flags;
14626
14627   mp->entry.crypto_algorithm = crypto_alg;
14628   mp->entry.integrity_algorithm = integ_alg;
14629   mp->entry.crypto_key.length = vec_len (ck);
14630   mp->entry.integrity_key.length = vec_len (ik);
14631
14632   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14633     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14634
14635   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14636     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14637
14638   if (ck)
14639     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14640   if (ik)
14641     clib_memcpy (mp->entry.integrity_key.data, ik,
14642                  mp->entry.integrity_key.length);
14643
14644   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14645     {
14646       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14647                    sizeof (mp->entry.tunnel_src));
14648       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14649                    sizeof (mp->entry.tunnel_dst));
14650     }
14651
14652   S (mp);
14653   W (ret);
14654   return ret;
14655 }
14656
14657 static int
14658 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14659 {
14660   unformat_input_t *i = vam->input;
14661   vl_api_ipsec_tunnel_if_add_del_t *mp;
14662   u32 local_spi = 0, remote_spi = 0;
14663   u32 crypto_alg = 0, integ_alg = 0;
14664   u8 *lck = NULL, *rck = NULL;
14665   u8 *lik = NULL, *rik = NULL;
14666   vl_api_address_t local_ip = { 0 };
14667   vl_api_address_t remote_ip = { 0 };
14668   f64 before = 0;
14669   u8 is_add = 1;
14670   u8 esn = 0;
14671   u8 anti_replay = 0;
14672   u8 renumber = 0;
14673   u32 instance = ~0;
14674   u32 count = 1, jj;
14675   int ret = -1;
14676
14677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (i, "del"))
14680         is_add = 0;
14681       else if (unformat (i, "esn"))
14682         esn = 1;
14683       else if (unformat (i, "anti-replay"))
14684         anti_replay = 1;
14685       else if (unformat (i, "count %d", &count))
14686         ;
14687       else if (unformat (i, "local_spi %d", &local_spi))
14688         ;
14689       else if (unformat (i, "remote_spi %d", &remote_spi))
14690         ;
14691       else
14692         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14693         ;
14694       else
14695         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14696         ;
14697       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14698         ;
14699       else
14700         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14701         ;
14702       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14703         ;
14704       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14705         ;
14706       else
14707         if (unformat
14708             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14709         {
14710           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14711             {
14712               errmsg ("unsupported crypto-alg: '%U'\n",
14713                       format_ipsec_crypto_alg, crypto_alg);
14714               return -99;
14715             }
14716         }
14717       else
14718         if (unformat
14719             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14720         {
14721           if (integ_alg >= IPSEC_INTEG_N_ALG)
14722             {
14723               errmsg ("unsupported integ-alg: '%U'\n",
14724                       format_ipsec_integ_alg, integ_alg);
14725               return -99;
14726             }
14727         }
14728       else if (unformat (i, "instance %u", &instance))
14729         renumber = 1;
14730       else
14731         {
14732           errmsg ("parse error '%U'\n", format_unformat_error, i);
14733           return -99;
14734         }
14735     }
14736
14737   if (count > 1)
14738     {
14739       /* Turn on async mode */
14740       vam->async_mode = 1;
14741       vam->async_errors = 0;
14742       before = vat_time_now (vam);
14743     }
14744
14745   for (jj = 0; jj < count; jj++)
14746     {
14747       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14748
14749       mp->is_add = is_add;
14750       mp->esn = esn;
14751       mp->anti_replay = anti_replay;
14752
14753       if (jj > 0)
14754         increment_address (&remote_ip);
14755
14756       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14757       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14758
14759       mp->local_spi = htonl (local_spi + jj);
14760       mp->remote_spi = htonl (remote_spi + jj);
14761       mp->crypto_alg = (u8) crypto_alg;
14762
14763       mp->local_crypto_key_len = 0;
14764       if (lck)
14765         {
14766           mp->local_crypto_key_len = vec_len (lck);
14767           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14768             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14769           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14770         }
14771
14772       mp->remote_crypto_key_len = 0;
14773       if (rck)
14774         {
14775           mp->remote_crypto_key_len = vec_len (rck);
14776           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14777             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14778           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14779         }
14780
14781       mp->integ_alg = (u8) integ_alg;
14782
14783       mp->local_integ_key_len = 0;
14784       if (lik)
14785         {
14786           mp->local_integ_key_len = vec_len (lik);
14787           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14788             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14789           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14790         }
14791
14792       mp->remote_integ_key_len = 0;
14793       if (rik)
14794         {
14795           mp->remote_integ_key_len = vec_len (rik);
14796           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14797             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14798           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14799         }
14800
14801       if (renumber)
14802         {
14803           mp->renumber = renumber;
14804           mp->show_instance = ntohl (instance);
14805         }
14806       S (mp);
14807     }
14808
14809   /* When testing multiple add/del ops, use a control-ping to sync */
14810   if (count > 1)
14811     {
14812       vl_api_control_ping_t *mp_ping;
14813       f64 after;
14814       f64 timeout;
14815
14816       /* Shut off async mode */
14817       vam->async_mode = 0;
14818
14819       MPING (CONTROL_PING, mp_ping);
14820       S (mp_ping);
14821
14822       timeout = vat_time_now (vam) + 1.0;
14823       while (vat_time_now (vam) < timeout)
14824         if (vam->result_ready == 1)
14825           goto out;
14826       vam->retval = -99;
14827
14828     out:
14829       if (vam->retval == -99)
14830         errmsg ("timeout");
14831
14832       if (vam->async_errors > 0)
14833         {
14834           errmsg ("%d asynchronous errors", vam->async_errors);
14835           vam->retval = -98;
14836         }
14837       vam->async_errors = 0;
14838       after = vat_time_now (vam);
14839
14840       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14841       if (jj > 0)
14842         count = jj;
14843
14844       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14845              count, after - before, count / (after - before));
14846     }
14847   else
14848     {
14849       /* Wait for a reply... */
14850       W (ret);
14851       return ret;
14852     }
14853
14854   return ret;
14855 }
14856
14857 static void
14858 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14859 {
14860   vat_main_t *vam = &vat_main;
14861
14862   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14863          "crypto_key %U integ_alg %u integ_key %U flags %x "
14864          "tunnel_src_addr %U tunnel_dst_addr %U "
14865          "salt %u seq_outbound %lu last_seq_inbound %lu "
14866          "replay_window %lu\n",
14867          ntohl (mp->entry.sad_id),
14868          ntohl (mp->sw_if_index),
14869          ntohl (mp->entry.spi),
14870          ntohl (mp->entry.protocol),
14871          ntohl (mp->entry.crypto_algorithm),
14872          format_hex_bytes, mp->entry.crypto_key.data,
14873          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14874          format_hex_bytes, mp->entry.integrity_key.data,
14875          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14876          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14877          &mp->entry.tunnel_dst, ntohl (mp->salt),
14878          clib_net_to_host_u64 (mp->seq_outbound),
14879          clib_net_to_host_u64 (mp->last_seq_inbound),
14880          clib_net_to_host_u64 (mp->replay_window));
14881 }
14882
14883 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14884 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14885
14886 static void vl_api_ipsec_sa_details_t_handler_json
14887   (vl_api_ipsec_sa_details_t * mp)
14888 {
14889   vat_main_t *vam = &vat_main;
14890   vat_json_node_t *node = NULL;
14891   vl_api_ipsec_sad_flags_t flags;
14892
14893   if (VAT_JSON_ARRAY != vam->json_tree.type)
14894     {
14895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14896       vat_json_init_array (&vam->json_tree);
14897     }
14898   node = vat_json_array_add (&vam->json_tree);
14899
14900   vat_json_init_object (node);
14901   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14902   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14903   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14904   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14905   vat_json_object_add_uint (node, "crypto_alg",
14906                             ntohl (mp->entry.crypto_algorithm));
14907   vat_json_object_add_uint (node, "integ_alg",
14908                             ntohl (mp->entry.integrity_algorithm));
14909   flags = ntohl (mp->entry.flags);
14910   vat_json_object_add_uint (node, "use_esn",
14911                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14912   vat_json_object_add_uint (node, "use_anti_replay",
14913                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14914   vat_json_object_add_uint (node, "is_tunnel",
14915                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14916   vat_json_object_add_uint (node, "is_tunnel_ip6",
14917                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14918   vat_json_object_add_uint (node, "udp_encap",
14919                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14920   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14921                              mp->entry.crypto_key.length);
14922   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14923                              mp->entry.integrity_key.length);
14924   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14925   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14926   vat_json_object_add_uint (node, "replay_window",
14927                             clib_net_to_host_u64 (mp->replay_window));
14928 }
14929
14930 static int
14931 api_ipsec_sa_dump (vat_main_t * vam)
14932 {
14933   unformat_input_t *i = vam->input;
14934   vl_api_ipsec_sa_dump_t *mp;
14935   vl_api_control_ping_t *mp_ping;
14936   u32 sa_id = ~0;
14937   int ret;
14938
14939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14940     {
14941       if (unformat (i, "sa_id %d", &sa_id))
14942         ;
14943       else
14944         {
14945           clib_warning ("parse error '%U'", format_unformat_error, i);
14946           return -99;
14947         }
14948     }
14949
14950   M (IPSEC_SA_DUMP, mp);
14951
14952   mp->sa_id = ntohl (sa_id);
14953
14954   S (mp);
14955
14956   /* Use a control ping for synchronization */
14957   M (CONTROL_PING, mp_ping);
14958   S (mp_ping);
14959
14960   W (ret);
14961   return ret;
14962 }
14963
14964 static int
14965 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14966 {
14967   unformat_input_t *i = vam->input;
14968   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14969   u32 sw_if_index = ~0;
14970   u32 sa_id = ~0;
14971   u8 is_outbound = (u8) ~ 0;
14972   int ret;
14973
14974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14977         ;
14978       else if (unformat (i, "sa_id %d", &sa_id))
14979         ;
14980       else if (unformat (i, "outbound"))
14981         is_outbound = 1;
14982       else if (unformat (i, "inbound"))
14983         is_outbound = 0;
14984       else
14985         {
14986           clib_warning ("parse error '%U'", format_unformat_error, i);
14987           return -99;
14988         }
14989     }
14990
14991   if (sw_if_index == ~0)
14992     {
14993       errmsg ("interface must be specified");
14994       return -99;
14995     }
14996
14997   if (sa_id == ~0)
14998     {
14999       errmsg ("SA ID must be specified");
15000       return -99;
15001     }
15002
15003   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15004
15005   mp->sw_if_index = htonl (sw_if_index);
15006   mp->sa_id = htonl (sa_id);
15007   mp->is_outbound = is_outbound;
15008
15009   S (mp);
15010   W (ret);
15011
15012   return ret;
15013 }
15014
15015 static int
15016 api_get_first_msg_id (vat_main_t * vam)
15017 {
15018   vl_api_get_first_msg_id_t *mp;
15019   unformat_input_t *i = vam->input;
15020   u8 *name;
15021   u8 name_set = 0;
15022   int ret;
15023
15024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15025     {
15026       if (unformat (i, "client %s", &name))
15027         name_set = 1;
15028       else
15029         break;
15030     }
15031
15032   if (name_set == 0)
15033     {
15034       errmsg ("missing client name");
15035       return -99;
15036     }
15037   vec_add1 (name, 0);
15038
15039   if (vec_len (name) > 63)
15040     {
15041       errmsg ("client name too long");
15042       return -99;
15043     }
15044
15045   M (GET_FIRST_MSG_ID, mp);
15046   clib_memcpy (mp->name, name, vec_len (name));
15047   S (mp);
15048   W (ret);
15049   return ret;
15050 }
15051
15052 static int
15053 api_cop_interface_enable_disable (vat_main_t * vam)
15054 {
15055   unformat_input_t *line_input = vam->input;
15056   vl_api_cop_interface_enable_disable_t *mp;
15057   u32 sw_if_index = ~0;
15058   u8 enable_disable = 1;
15059   int ret;
15060
15061   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (line_input, "disable"))
15064         enable_disable = 0;
15065       if (unformat (line_input, "enable"))
15066         enable_disable = 1;
15067       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15068                          vam, &sw_if_index))
15069         ;
15070       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15071         ;
15072       else
15073         break;
15074     }
15075
15076   if (sw_if_index == ~0)
15077     {
15078       errmsg ("missing interface name or sw_if_index");
15079       return -99;
15080     }
15081
15082   /* Construct the API message */
15083   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15084   mp->sw_if_index = ntohl (sw_if_index);
15085   mp->enable_disable = enable_disable;
15086
15087   /* send it... */
15088   S (mp);
15089   /* Wait for the reply */
15090   W (ret);
15091   return ret;
15092 }
15093
15094 static int
15095 api_cop_whitelist_enable_disable (vat_main_t * vam)
15096 {
15097   unformat_input_t *line_input = vam->input;
15098   vl_api_cop_whitelist_enable_disable_t *mp;
15099   u32 sw_if_index = ~0;
15100   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15101   u32 fib_id = 0;
15102   int ret;
15103
15104   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15105     {
15106       if (unformat (line_input, "ip4"))
15107         ip4 = 1;
15108       else if (unformat (line_input, "ip6"))
15109         ip6 = 1;
15110       else if (unformat (line_input, "default"))
15111         default_cop = 1;
15112       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15113                          vam, &sw_if_index))
15114         ;
15115       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15116         ;
15117       else if (unformat (line_input, "fib-id %d", &fib_id))
15118         ;
15119       else
15120         break;
15121     }
15122
15123   if (sw_if_index == ~0)
15124     {
15125       errmsg ("missing interface name or sw_if_index");
15126       return -99;
15127     }
15128
15129   /* Construct the API message */
15130   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15131   mp->sw_if_index = ntohl (sw_if_index);
15132   mp->fib_id = ntohl (fib_id);
15133   mp->ip4 = ip4;
15134   mp->ip6 = ip6;
15135   mp->default_cop = default_cop;
15136
15137   /* send it... */
15138   S (mp);
15139   /* Wait for the reply */
15140   W (ret);
15141   return ret;
15142 }
15143
15144 static int
15145 api_get_node_graph (vat_main_t * vam)
15146 {
15147   vl_api_get_node_graph_t *mp;
15148   int ret;
15149
15150   M (GET_NODE_GRAPH, mp);
15151
15152   /* send it... */
15153   S (mp);
15154   /* Wait for the reply */
15155   W (ret);
15156   return ret;
15157 }
15158
15159 /* *INDENT-OFF* */
15160 /** Used for parsing LISP eids */
15161 typedef CLIB_PACKED(struct{
15162   u8 addr[16];   /**< eid address */
15163   u32 len;       /**< prefix length if IP */
15164   u8 type;      /**< type of eid */
15165 }) lisp_eid_vat_t;
15166 /* *INDENT-ON* */
15167
15168 static uword
15169 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15170 {
15171   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15172
15173   clib_memset (a, 0, sizeof (a[0]));
15174
15175   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15176     {
15177       a->type = 0;              /* ipv4 type */
15178     }
15179   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15180     {
15181       a->type = 1;              /* ipv6 type */
15182     }
15183   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15184     {
15185       a->type = 2;              /* mac type */
15186     }
15187   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15188     {
15189       a->type = 3;              /* NSH type */
15190       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15191       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15192     }
15193   else
15194     {
15195       return 0;
15196     }
15197
15198   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15199     {
15200       return 0;
15201     }
15202
15203   return 1;
15204 }
15205
15206 static int
15207 lisp_eid_size_vat (u8 type)
15208 {
15209   switch (type)
15210     {
15211     case 0:
15212       return 4;
15213     case 1:
15214       return 16;
15215     case 2:
15216       return 6;
15217     case 3:
15218       return 5;
15219     }
15220   return 0;
15221 }
15222
15223 static void
15224 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15225 {
15226   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15227 }
15228
15229 static int
15230 api_one_add_del_locator_set (vat_main_t * vam)
15231 {
15232   unformat_input_t *input = vam->input;
15233   vl_api_one_add_del_locator_set_t *mp;
15234   u8 is_add = 1;
15235   u8 *locator_set_name = NULL;
15236   u8 locator_set_name_set = 0;
15237   vl_api_local_locator_t locator, *locators = 0;
15238   u32 sw_if_index, priority, weight;
15239   u32 data_len = 0;
15240
15241   int ret;
15242   /* Parse args required to build the message */
15243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15244     {
15245       if (unformat (input, "del"))
15246         {
15247           is_add = 0;
15248         }
15249       else if (unformat (input, "locator-set %s", &locator_set_name))
15250         {
15251           locator_set_name_set = 1;
15252         }
15253       else if (unformat (input, "sw_if_index %u p %u w %u",
15254                          &sw_if_index, &priority, &weight))
15255         {
15256           locator.sw_if_index = htonl (sw_if_index);
15257           locator.priority = priority;
15258           locator.weight = weight;
15259           vec_add1 (locators, locator);
15260         }
15261       else
15262         if (unformat
15263             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15264              &sw_if_index, &priority, &weight))
15265         {
15266           locator.sw_if_index = htonl (sw_if_index);
15267           locator.priority = priority;
15268           locator.weight = weight;
15269           vec_add1 (locators, locator);
15270         }
15271       else
15272         break;
15273     }
15274
15275   if (locator_set_name_set == 0)
15276     {
15277       errmsg ("missing locator-set name");
15278       vec_free (locators);
15279       return -99;
15280     }
15281
15282   if (vec_len (locator_set_name) > 64)
15283     {
15284       errmsg ("locator-set name too long");
15285       vec_free (locator_set_name);
15286       vec_free (locators);
15287       return -99;
15288     }
15289   vec_add1 (locator_set_name, 0);
15290
15291   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15292
15293   /* Construct the API message */
15294   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15295
15296   mp->is_add = is_add;
15297   clib_memcpy (mp->locator_set_name, locator_set_name,
15298                vec_len (locator_set_name));
15299   vec_free (locator_set_name);
15300
15301   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15302   if (locators)
15303     clib_memcpy (mp->locators, locators, data_len);
15304   vec_free (locators);
15305
15306   /* send it... */
15307   S (mp);
15308
15309   /* Wait for a reply... */
15310   W (ret);
15311   return ret;
15312 }
15313
15314 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15315
15316 static int
15317 api_one_add_del_locator (vat_main_t * vam)
15318 {
15319   unformat_input_t *input = vam->input;
15320   vl_api_one_add_del_locator_t *mp;
15321   u32 tmp_if_index = ~0;
15322   u32 sw_if_index = ~0;
15323   u8 sw_if_index_set = 0;
15324   u8 sw_if_index_if_name_set = 0;
15325   u32 priority = ~0;
15326   u8 priority_set = 0;
15327   u32 weight = ~0;
15328   u8 weight_set = 0;
15329   u8 is_add = 1;
15330   u8 *locator_set_name = NULL;
15331   u8 locator_set_name_set = 0;
15332   int ret;
15333
15334   /* Parse args required to build the message */
15335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15336     {
15337       if (unformat (input, "del"))
15338         {
15339           is_add = 0;
15340         }
15341       else if (unformat (input, "locator-set %s", &locator_set_name))
15342         {
15343           locator_set_name_set = 1;
15344         }
15345       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15346                          &tmp_if_index))
15347         {
15348           sw_if_index_if_name_set = 1;
15349           sw_if_index = tmp_if_index;
15350         }
15351       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15352         {
15353           sw_if_index_set = 1;
15354           sw_if_index = tmp_if_index;
15355         }
15356       else if (unformat (input, "p %d", &priority))
15357         {
15358           priority_set = 1;
15359         }
15360       else if (unformat (input, "w %d", &weight))
15361         {
15362           weight_set = 1;
15363         }
15364       else
15365         break;
15366     }
15367
15368   if (locator_set_name_set == 0)
15369     {
15370       errmsg ("missing locator-set name");
15371       return -99;
15372     }
15373
15374   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15375     {
15376       errmsg ("missing sw_if_index");
15377       vec_free (locator_set_name);
15378       return -99;
15379     }
15380
15381   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15382     {
15383       errmsg ("cannot use both params interface name and sw_if_index");
15384       vec_free (locator_set_name);
15385       return -99;
15386     }
15387
15388   if (priority_set == 0)
15389     {
15390       errmsg ("missing locator-set priority");
15391       vec_free (locator_set_name);
15392       return -99;
15393     }
15394
15395   if (weight_set == 0)
15396     {
15397       errmsg ("missing locator-set weight");
15398       vec_free (locator_set_name);
15399       return -99;
15400     }
15401
15402   if (vec_len (locator_set_name) > 64)
15403     {
15404       errmsg ("locator-set name too long");
15405       vec_free (locator_set_name);
15406       return -99;
15407     }
15408   vec_add1 (locator_set_name, 0);
15409
15410   /* Construct the API message */
15411   M (ONE_ADD_DEL_LOCATOR, mp);
15412
15413   mp->is_add = is_add;
15414   mp->sw_if_index = ntohl (sw_if_index);
15415   mp->priority = priority;
15416   mp->weight = weight;
15417   clib_memcpy (mp->locator_set_name, locator_set_name,
15418                vec_len (locator_set_name));
15419   vec_free (locator_set_name);
15420
15421   /* send it... */
15422   S (mp);
15423
15424   /* Wait for a reply... */
15425   W (ret);
15426   return ret;
15427 }
15428
15429 #define api_lisp_add_del_locator api_one_add_del_locator
15430
15431 uword
15432 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15433 {
15434   u32 *key_id = va_arg (*args, u32 *);
15435   u8 *s = 0;
15436
15437   if (unformat (input, "%s", &s))
15438     {
15439       if (!strcmp ((char *) s, "sha1"))
15440         key_id[0] = HMAC_SHA_1_96;
15441       else if (!strcmp ((char *) s, "sha256"))
15442         key_id[0] = HMAC_SHA_256_128;
15443       else
15444         {
15445           clib_warning ("invalid key_id: '%s'", s);
15446           key_id[0] = HMAC_NO_KEY;
15447         }
15448     }
15449   else
15450     return 0;
15451
15452   vec_free (s);
15453   return 1;
15454 }
15455
15456 static int
15457 api_one_add_del_local_eid (vat_main_t * vam)
15458 {
15459   unformat_input_t *input = vam->input;
15460   vl_api_one_add_del_local_eid_t *mp;
15461   u8 is_add = 1;
15462   u8 eid_set = 0;
15463   lisp_eid_vat_t _eid, *eid = &_eid;
15464   u8 *locator_set_name = 0;
15465   u8 locator_set_name_set = 0;
15466   u32 vni = 0;
15467   u16 key_id = 0;
15468   u8 *key = 0;
15469   int ret;
15470
15471   /* Parse args required to build the message */
15472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15473     {
15474       if (unformat (input, "del"))
15475         {
15476           is_add = 0;
15477         }
15478       else if (unformat (input, "vni %d", &vni))
15479         {
15480           ;
15481         }
15482       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15483         {
15484           eid_set = 1;
15485         }
15486       else if (unformat (input, "locator-set %s", &locator_set_name))
15487         {
15488           locator_set_name_set = 1;
15489         }
15490       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15491         ;
15492       else if (unformat (input, "secret-key %_%v%_", &key))
15493         ;
15494       else
15495         break;
15496     }
15497
15498   if (locator_set_name_set == 0)
15499     {
15500       errmsg ("missing locator-set name");
15501       return -99;
15502     }
15503
15504   if (0 == eid_set)
15505     {
15506       errmsg ("EID address not set!");
15507       vec_free (locator_set_name);
15508       return -99;
15509     }
15510
15511   if (key && (0 == key_id))
15512     {
15513       errmsg ("invalid key_id!");
15514       return -99;
15515     }
15516
15517   if (vec_len (key) > 64)
15518     {
15519       errmsg ("key too long");
15520       vec_free (key);
15521       return -99;
15522     }
15523
15524   if (vec_len (locator_set_name) > 64)
15525     {
15526       errmsg ("locator-set name too long");
15527       vec_free (locator_set_name);
15528       return -99;
15529     }
15530   vec_add1 (locator_set_name, 0);
15531
15532   /* Construct the API message */
15533   M (ONE_ADD_DEL_LOCAL_EID, mp);
15534
15535   mp->is_add = is_add;
15536   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15537   mp->eid_type = eid->type;
15538   mp->prefix_len = eid->len;
15539   mp->vni = clib_host_to_net_u32 (vni);
15540   mp->key_id = clib_host_to_net_u16 (key_id);
15541   clib_memcpy (mp->locator_set_name, locator_set_name,
15542                vec_len (locator_set_name));
15543   clib_memcpy (mp->key, key, vec_len (key));
15544
15545   vec_free (locator_set_name);
15546   vec_free (key);
15547
15548   /* send it... */
15549   S (mp);
15550
15551   /* Wait for a reply... */
15552   W (ret);
15553   return ret;
15554 }
15555
15556 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15557
15558 static int
15559 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15560 {
15561   u32 dp_table = 0, vni = 0;;
15562   unformat_input_t *input = vam->input;
15563   vl_api_gpe_add_del_fwd_entry_t *mp;
15564   u8 is_add = 1;
15565   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15566   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15567   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15568   u32 action = ~0, w;
15569   ip4_address_t rmt_rloc4, lcl_rloc4;
15570   ip6_address_t rmt_rloc6, lcl_rloc6;
15571   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15572   int ret;
15573
15574   clib_memset (&rloc, 0, sizeof (rloc));
15575
15576   /* Parse args required to build the message */
15577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (input, "del"))
15580         is_add = 0;
15581       else if (unformat (input, "add"))
15582         is_add = 1;
15583       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15584         {
15585           rmt_eid_set = 1;
15586         }
15587       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15588         {
15589           lcl_eid_set = 1;
15590         }
15591       else if (unformat (input, "vrf %d", &dp_table))
15592         ;
15593       else if (unformat (input, "bd %d", &dp_table))
15594         ;
15595       else if (unformat (input, "vni %d", &vni))
15596         ;
15597       else if (unformat (input, "w %d", &w))
15598         {
15599           if (!curr_rloc)
15600             {
15601               errmsg ("No RLOC configured for setting priority/weight!");
15602               return -99;
15603             }
15604           curr_rloc->weight = w;
15605         }
15606       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15607                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15608         {
15609           rloc.is_ip4 = 1;
15610
15611           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15612           rloc.weight = 0;
15613           vec_add1 (lcl_locs, rloc);
15614
15615           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15616           vec_add1 (rmt_locs, rloc);
15617           /* weight saved in rmt loc */
15618           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15619         }
15620       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15621                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15622         {
15623           rloc.is_ip4 = 0;
15624           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15625           rloc.weight = 0;
15626           vec_add1 (lcl_locs, rloc);
15627
15628           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15629           vec_add1 (rmt_locs, rloc);
15630           /* weight saved in rmt loc */
15631           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15632         }
15633       else if (unformat (input, "action %d", &action))
15634         {
15635           ;
15636         }
15637       else
15638         {
15639           clib_warning ("parse error '%U'", format_unformat_error, input);
15640           return -99;
15641         }
15642     }
15643
15644   if (!rmt_eid_set)
15645     {
15646       errmsg ("remote eid addresses not set");
15647       return -99;
15648     }
15649
15650   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15651     {
15652       errmsg ("eid types don't match");
15653       return -99;
15654     }
15655
15656   if (0 == rmt_locs && (u32) ~ 0 == action)
15657     {
15658       errmsg ("action not set for negative mapping");
15659       return -99;
15660     }
15661
15662   /* Construct the API message */
15663   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15664       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15665
15666   mp->is_add = is_add;
15667   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15668   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15669   mp->eid_type = rmt_eid->type;
15670   mp->dp_table = clib_host_to_net_u32 (dp_table);
15671   mp->vni = clib_host_to_net_u32 (vni);
15672   mp->rmt_len = rmt_eid->len;
15673   mp->lcl_len = lcl_eid->len;
15674   mp->action = action;
15675
15676   if (0 != rmt_locs && 0 != lcl_locs)
15677     {
15678       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15679       clib_memcpy (mp->locs, lcl_locs,
15680                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15681
15682       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15683       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15684                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15685     }
15686   vec_free (lcl_locs);
15687   vec_free (rmt_locs);
15688
15689   /* send it... */
15690   S (mp);
15691
15692   /* Wait for a reply... */
15693   W (ret);
15694   return ret;
15695 }
15696
15697 static int
15698 api_one_add_del_map_server (vat_main_t * vam)
15699 {
15700   unformat_input_t *input = vam->input;
15701   vl_api_one_add_del_map_server_t *mp;
15702   u8 is_add = 1;
15703   u8 ipv4_set = 0;
15704   u8 ipv6_set = 0;
15705   ip4_address_t ipv4;
15706   ip6_address_t ipv6;
15707   int ret;
15708
15709   /* Parse args required to build the message */
15710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (input, "del"))
15713         {
15714           is_add = 0;
15715         }
15716       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15717         {
15718           ipv4_set = 1;
15719         }
15720       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15721         {
15722           ipv6_set = 1;
15723         }
15724       else
15725         break;
15726     }
15727
15728   if (ipv4_set && ipv6_set)
15729     {
15730       errmsg ("both eid v4 and v6 addresses set");
15731       return -99;
15732     }
15733
15734   if (!ipv4_set && !ipv6_set)
15735     {
15736       errmsg ("eid addresses not set");
15737       return -99;
15738     }
15739
15740   /* Construct the API message */
15741   M (ONE_ADD_DEL_MAP_SERVER, mp);
15742
15743   mp->is_add = is_add;
15744   if (ipv6_set)
15745     {
15746       mp->is_ipv6 = 1;
15747       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15748     }
15749   else
15750     {
15751       mp->is_ipv6 = 0;
15752       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15753     }
15754
15755   /* send it... */
15756   S (mp);
15757
15758   /* Wait for a reply... */
15759   W (ret);
15760   return ret;
15761 }
15762
15763 #define api_lisp_add_del_map_server api_one_add_del_map_server
15764
15765 static int
15766 api_one_add_del_map_resolver (vat_main_t * vam)
15767 {
15768   unformat_input_t *input = vam->input;
15769   vl_api_one_add_del_map_resolver_t *mp;
15770   u8 is_add = 1;
15771   u8 ipv4_set = 0;
15772   u8 ipv6_set = 0;
15773   ip4_address_t ipv4;
15774   ip6_address_t ipv6;
15775   int ret;
15776
15777   /* Parse args required to build the message */
15778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15779     {
15780       if (unformat (input, "del"))
15781         {
15782           is_add = 0;
15783         }
15784       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15785         {
15786           ipv4_set = 1;
15787         }
15788       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15789         {
15790           ipv6_set = 1;
15791         }
15792       else
15793         break;
15794     }
15795
15796   if (ipv4_set && ipv6_set)
15797     {
15798       errmsg ("both eid v4 and v6 addresses set");
15799       return -99;
15800     }
15801
15802   if (!ipv4_set && !ipv6_set)
15803     {
15804       errmsg ("eid addresses not set");
15805       return -99;
15806     }
15807
15808   /* Construct the API message */
15809   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15810
15811   mp->is_add = is_add;
15812   if (ipv6_set)
15813     {
15814       mp->is_ipv6 = 1;
15815       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15816     }
15817   else
15818     {
15819       mp->is_ipv6 = 0;
15820       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15821     }
15822
15823   /* send it... */
15824   S (mp);
15825
15826   /* Wait for a reply... */
15827   W (ret);
15828   return ret;
15829 }
15830
15831 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15832
15833 static int
15834 api_lisp_gpe_enable_disable (vat_main_t * vam)
15835 {
15836   unformat_input_t *input = vam->input;
15837   vl_api_gpe_enable_disable_t *mp;
15838   u8 is_set = 0;
15839   u8 is_en = 1;
15840   int ret;
15841
15842   /* Parse args required to build the message */
15843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15844     {
15845       if (unformat (input, "enable"))
15846         {
15847           is_set = 1;
15848           is_en = 1;
15849         }
15850       else if (unformat (input, "disable"))
15851         {
15852           is_set = 1;
15853           is_en = 0;
15854         }
15855       else
15856         break;
15857     }
15858
15859   if (is_set == 0)
15860     {
15861       errmsg ("Value not set");
15862       return -99;
15863     }
15864
15865   /* Construct the API message */
15866   M (GPE_ENABLE_DISABLE, mp);
15867
15868   mp->is_en = is_en;
15869
15870   /* send it... */
15871   S (mp);
15872
15873   /* Wait for a reply... */
15874   W (ret);
15875   return ret;
15876 }
15877
15878 static int
15879 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15880 {
15881   unformat_input_t *input = vam->input;
15882   vl_api_one_rloc_probe_enable_disable_t *mp;
15883   u8 is_set = 0;
15884   u8 is_en = 0;
15885   int ret;
15886
15887   /* Parse args required to build the message */
15888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15889     {
15890       if (unformat (input, "enable"))
15891         {
15892           is_set = 1;
15893           is_en = 1;
15894         }
15895       else if (unformat (input, "disable"))
15896         is_set = 1;
15897       else
15898         break;
15899     }
15900
15901   if (!is_set)
15902     {
15903       errmsg ("Value not set");
15904       return -99;
15905     }
15906
15907   /* Construct the API message */
15908   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15909
15910   mp->is_enabled = is_en;
15911
15912   /* send it... */
15913   S (mp);
15914
15915   /* Wait for a reply... */
15916   W (ret);
15917   return ret;
15918 }
15919
15920 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15921
15922 static int
15923 api_one_map_register_enable_disable (vat_main_t * vam)
15924 {
15925   unformat_input_t *input = vam->input;
15926   vl_api_one_map_register_enable_disable_t *mp;
15927   u8 is_set = 0;
15928   u8 is_en = 0;
15929   int ret;
15930
15931   /* Parse args required to build the message */
15932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15933     {
15934       if (unformat (input, "enable"))
15935         {
15936           is_set = 1;
15937           is_en = 1;
15938         }
15939       else if (unformat (input, "disable"))
15940         is_set = 1;
15941       else
15942         break;
15943     }
15944
15945   if (!is_set)
15946     {
15947       errmsg ("Value not set");
15948       return -99;
15949     }
15950
15951   /* Construct the API message */
15952   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15953
15954   mp->is_enabled = is_en;
15955
15956   /* send it... */
15957   S (mp);
15958
15959   /* Wait for a reply... */
15960   W (ret);
15961   return ret;
15962 }
15963
15964 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15965
15966 static int
15967 api_one_enable_disable (vat_main_t * vam)
15968 {
15969   unformat_input_t *input = vam->input;
15970   vl_api_one_enable_disable_t *mp;
15971   u8 is_set = 0;
15972   u8 is_en = 0;
15973   int ret;
15974
15975   /* Parse args required to build the message */
15976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15977     {
15978       if (unformat (input, "enable"))
15979         {
15980           is_set = 1;
15981           is_en = 1;
15982         }
15983       else if (unformat (input, "disable"))
15984         {
15985           is_set = 1;
15986         }
15987       else
15988         break;
15989     }
15990
15991   if (!is_set)
15992     {
15993       errmsg ("Value not set");
15994       return -99;
15995     }
15996
15997   /* Construct the API message */
15998   M (ONE_ENABLE_DISABLE, mp);
15999
16000   mp->is_en = is_en;
16001
16002   /* send it... */
16003   S (mp);
16004
16005   /* Wait for a reply... */
16006   W (ret);
16007   return ret;
16008 }
16009
16010 #define api_lisp_enable_disable api_one_enable_disable
16011
16012 static int
16013 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16014 {
16015   unformat_input_t *input = vam->input;
16016   vl_api_one_enable_disable_xtr_mode_t *mp;
16017   u8 is_set = 0;
16018   u8 is_en = 0;
16019   int ret;
16020
16021   /* Parse args required to build the message */
16022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16023     {
16024       if (unformat (input, "enable"))
16025         {
16026           is_set = 1;
16027           is_en = 1;
16028         }
16029       else if (unformat (input, "disable"))
16030         {
16031           is_set = 1;
16032         }
16033       else
16034         break;
16035     }
16036
16037   if (!is_set)
16038     {
16039       errmsg ("Value not set");
16040       return -99;
16041     }
16042
16043   /* Construct the API message */
16044   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16045
16046   mp->is_en = is_en;
16047
16048   /* send it... */
16049   S (mp);
16050
16051   /* Wait for a reply... */
16052   W (ret);
16053   return ret;
16054 }
16055
16056 static int
16057 api_one_show_xtr_mode (vat_main_t * vam)
16058 {
16059   vl_api_one_show_xtr_mode_t *mp;
16060   int ret;
16061
16062   /* Construct the API message */
16063   M (ONE_SHOW_XTR_MODE, mp);
16064
16065   /* send it... */
16066   S (mp);
16067
16068   /* Wait for a reply... */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16075 {
16076   unformat_input_t *input = vam->input;
16077   vl_api_one_enable_disable_pitr_mode_t *mp;
16078   u8 is_set = 0;
16079   u8 is_en = 0;
16080   int ret;
16081
16082   /* Parse args required to build the message */
16083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (input, "enable"))
16086         {
16087           is_set = 1;
16088           is_en = 1;
16089         }
16090       else if (unformat (input, "disable"))
16091         {
16092           is_set = 1;
16093         }
16094       else
16095         break;
16096     }
16097
16098   if (!is_set)
16099     {
16100       errmsg ("Value not set");
16101       return -99;
16102     }
16103
16104   /* Construct the API message */
16105   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16106
16107   mp->is_en = is_en;
16108
16109   /* send it... */
16110   S (mp);
16111
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_one_show_pitr_mode (vat_main_t * vam)
16119 {
16120   vl_api_one_show_pitr_mode_t *mp;
16121   int ret;
16122
16123   /* Construct the API message */
16124   M (ONE_SHOW_PITR_MODE, mp);
16125
16126   /* send it... */
16127   S (mp);
16128
16129   /* Wait for a reply... */
16130   W (ret);
16131   return ret;
16132 }
16133
16134 static int
16135 api_one_enable_disable_petr_mode (vat_main_t * vam)
16136 {
16137   unformat_input_t *input = vam->input;
16138   vl_api_one_enable_disable_petr_mode_t *mp;
16139   u8 is_set = 0;
16140   u8 is_en = 0;
16141   int ret;
16142
16143   /* Parse args required to build the message */
16144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (input, "enable"))
16147         {
16148           is_set = 1;
16149           is_en = 1;
16150         }
16151       else if (unformat (input, "disable"))
16152         {
16153           is_set = 1;
16154         }
16155       else
16156         break;
16157     }
16158
16159   if (!is_set)
16160     {
16161       errmsg ("Value not set");
16162       return -99;
16163     }
16164
16165   /* Construct the API message */
16166   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16167
16168   mp->is_en = is_en;
16169
16170   /* send it... */
16171   S (mp);
16172
16173   /* Wait for a reply... */
16174   W (ret);
16175   return ret;
16176 }
16177
16178 static int
16179 api_one_show_petr_mode (vat_main_t * vam)
16180 {
16181   vl_api_one_show_petr_mode_t *mp;
16182   int ret;
16183
16184   /* Construct the API message */
16185   M (ONE_SHOW_PETR_MODE, mp);
16186
16187   /* send it... */
16188   S (mp);
16189
16190   /* Wait for a reply... */
16191   W (ret);
16192   return ret;
16193 }
16194
16195 static int
16196 api_show_one_map_register_state (vat_main_t * vam)
16197 {
16198   vl_api_show_one_map_register_state_t *mp;
16199   int ret;
16200
16201   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16202
16203   /* send */
16204   S (mp);
16205
16206   /* wait for reply */
16207   W (ret);
16208   return ret;
16209 }
16210
16211 #define api_show_lisp_map_register_state api_show_one_map_register_state
16212
16213 static int
16214 api_show_one_rloc_probe_state (vat_main_t * vam)
16215 {
16216   vl_api_show_one_rloc_probe_state_t *mp;
16217   int ret;
16218
16219   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16220
16221   /* send */
16222   S (mp);
16223
16224   /* wait for reply */
16225   W (ret);
16226   return ret;
16227 }
16228
16229 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16230
16231 static int
16232 api_one_add_del_ndp_entry (vat_main_t * vam)
16233 {
16234   vl_api_one_add_del_ndp_entry_t *mp;
16235   unformat_input_t *input = vam->input;
16236   u8 is_add = 1;
16237   u8 mac_set = 0;
16238   u8 bd_set = 0;
16239   u8 ip_set = 0;
16240   u8 mac[6] = { 0, };
16241   u8 ip6[16] = { 0, };
16242   u32 bd = ~0;
16243   int ret;
16244
16245   /* Parse args required to build the message */
16246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16247     {
16248       if (unformat (input, "del"))
16249         is_add = 0;
16250       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16251         mac_set = 1;
16252       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16253         ip_set = 1;
16254       else if (unformat (input, "bd %d", &bd))
16255         bd_set = 1;
16256       else
16257         {
16258           errmsg ("parse error '%U'", format_unformat_error, input);
16259           return -99;
16260         }
16261     }
16262
16263   if (!bd_set || !ip_set || (!mac_set && is_add))
16264     {
16265       errmsg ("Missing BD, IP or MAC!");
16266       return -99;
16267     }
16268
16269   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16270   mp->is_add = is_add;
16271   clib_memcpy (mp->mac, mac, 6);
16272   mp->bd = clib_host_to_net_u32 (bd);
16273   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16274
16275   /* send */
16276   S (mp);
16277
16278   /* wait for reply */
16279   W (ret);
16280   return ret;
16281 }
16282
16283 static int
16284 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16285 {
16286   vl_api_one_add_del_l2_arp_entry_t *mp;
16287   unformat_input_t *input = vam->input;
16288   u8 is_add = 1;
16289   u8 mac_set = 0;
16290   u8 bd_set = 0;
16291   u8 ip_set = 0;
16292   u8 mac[6] = { 0, };
16293   u32 ip4 = 0, bd = ~0;
16294   int ret;
16295
16296   /* Parse args required to build the message */
16297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16298     {
16299       if (unformat (input, "del"))
16300         is_add = 0;
16301       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16302         mac_set = 1;
16303       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16304         ip_set = 1;
16305       else if (unformat (input, "bd %d", &bd))
16306         bd_set = 1;
16307       else
16308         {
16309           errmsg ("parse error '%U'", format_unformat_error, input);
16310           return -99;
16311         }
16312     }
16313
16314   if (!bd_set || !ip_set || (!mac_set && is_add))
16315     {
16316       errmsg ("Missing BD, IP or MAC!");
16317       return -99;
16318     }
16319
16320   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16321   mp->is_add = is_add;
16322   clib_memcpy (mp->mac, mac, 6);
16323   mp->bd = clib_host_to_net_u32 (bd);
16324   mp->ip4 = ip4;
16325
16326   /* send */
16327   S (mp);
16328
16329   /* wait for reply */
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_one_ndp_bd_get (vat_main_t * vam)
16336 {
16337   vl_api_one_ndp_bd_get_t *mp;
16338   int ret;
16339
16340   M (ONE_NDP_BD_GET, mp);
16341
16342   /* send */
16343   S (mp);
16344
16345   /* wait for reply */
16346   W (ret);
16347   return ret;
16348 }
16349
16350 static int
16351 api_one_ndp_entries_get (vat_main_t * vam)
16352 {
16353   vl_api_one_ndp_entries_get_t *mp;
16354   unformat_input_t *input = vam->input;
16355   u8 bd_set = 0;
16356   u32 bd = ~0;
16357   int ret;
16358
16359   /* Parse args required to build the message */
16360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16361     {
16362       if (unformat (input, "bd %d", &bd))
16363         bd_set = 1;
16364       else
16365         {
16366           errmsg ("parse error '%U'", format_unformat_error, input);
16367           return -99;
16368         }
16369     }
16370
16371   if (!bd_set)
16372     {
16373       errmsg ("Expected bridge domain!");
16374       return -99;
16375     }
16376
16377   M (ONE_NDP_ENTRIES_GET, mp);
16378   mp->bd = clib_host_to_net_u32 (bd);
16379
16380   /* send */
16381   S (mp);
16382
16383   /* wait for reply */
16384   W (ret);
16385   return ret;
16386 }
16387
16388 static int
16389 api_one_l2_arp_bd_get (vat_main_t * vam)
16390 {
16391   vl_api_one_l2_arp_bd_get_t *mp;
16392   int ret;
16393
16394   M (ONE_L2_ARP_BD_GET, mp);
16395
16396   /* send */
16397   S (mp);
16398
16399   /* wait for reply */
16400   W (ret);
16401   return ret;
16402 }
16403
16404 static int
16405 api_one_l2_arp_entries_get (vat_main_t * vam)
16406 {
16407   vl_api_one_l2_arp_entries_get_t *mp;
16408   unformat_input_t *input = vam->input;
16409   u8 bd_set = 0;
16410   u32 bd = ~0;
16411   int ret;
16412
16413   /* Parse args required to build the message */
16414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16415     {
16416       if (unformat (input, "bd %d", &bd))
16417         bd_set = 1;
16418       else
16419         {
16420           errmsg ("parse error '%U'", format_unformat_error, input);
16421           return -99;
16422         }
16423     }
16424
16425   if (!bd_set)
16426     {
16427       errmsg ("Expected bridge domain!");
16428       return -99;
16429     }
16430
16431   M (ONE_L2_ARP_ENTRIES_GET, mp);
16432   mp->bd = clib_host_to_net_u32 (bd);
16433
16434   /* send */
16435   S (mp);
16436
16437   /* wait for reply */
16438   W (ret);
16439   return ret;
16440 }
16441
16442 static int
16443 api_one_stats_enable_disable (vat_main_t * vam)
16444 {
16445   vl_api_one_stats_enable_disable_t *mp;
16446   unformat_input_t *input = vam->input;
16447   u8 is_set = 0;
16448   u8 is_en = 0;
16449   int ret;
16450
16451   /* Parse args required to build the message */
16452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16453     {
16454       if (unformat (input, "enable"))
16455         {
16456           is_set = 1;
16457           is_en = 1;
16458         }
16459       else if (unformat (input, "disable"))
16460         {
16461           is_set = 1;
16462         }
16463       else
16464         break;
16465     }
16466
16467   if (!is_set)
16468     {
16469       errmsg ("Value not set");
16470       return -99;
16471     }
16472
16473   M (ONE_STATS_ENABLE_DISABLE, mp);
16474   mp->is_en = is_en;
16475
16476   /* send */
16477   S (mp);
16478
16479   /* wait for reply */
16480   W (ret);
16481   return ret;
16482 }
16483
16484 static int
16485 api_show_one_stats_enable_disable (vat_main_t * vam)
16486 {
16487   vl_api_show_one_stats_enable_disable_t *mp;
16488   int ret;
16489
16490   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16491
16492   /* send */
16493   S (mp);
16494
16495   /* wait for reply */
16496   W (ret);
16497   return ret;
16498 }
16499
16500 static int
16501 api_show_one_map_request_mode (vat_main_t * vam)
16502 {
16503   vl_api_show_one_map_request_mode_t *mp;
16504   int ret;
16505
16506   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16507
16508   /* send */
16509   S (mp);
16510
16511   /* wait for reply */
16512   W (ret);
16513   return ret;
16514 }
16515
16516 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16517
16518 static int
16519 api_one_map_request_mode (vat_main_t * vam)
16520 {
16521   unformat_input_t *input = vam->input;
16522   vl_api_one_map_request_mode_t *mp;
16523   u8 mode = 0;
16524   int ret;
16525
16526   /* Parse args required to build the message */
16527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16528     {
16529       if (unformat (input, "dst-only"))
16530         mode = 0;
16531       else if (unformat (input, "src-dst"))
16532         mode = 1;
16533       else
16534         {
16535           errmsg ("parse error '%U'", format_unformat_error, input);
16536           return -99;
16537         }
16538     }
16539
16540   M (ONE_MAP_REQUEST_MODE, mp);
16541
16542   mp->mode = mode;
16543
16544   /* send */
16545   S (mp);
16546
16547   /* wait for reply */
16548   W (ret);
16549   return ret;
16550 }
16551
16552 #define api_lisp_map_request_mode api_one_map_request_mode
16553
16554 /**
16555  * Enable/disable ONE proxy ITR.
16556  *
16557  * @param vam vpp API test context
16558  * @return return code
16559  */
16560 static int
16561 api_one_pitr_set_locator_set (vat_main_t * vam)
16562 {
16563   u8 ls_name_set = 0;
16564   unformat_input_t *input = vam->input;
16565   vl_api_one_pitr_set_locator_set_t *mp;
16566   u8 is_add = 1;
16567   u8 *ls_name = 0;
16568   int ret;
16569
16570   /* Parse args required to build the message */
16571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (input, "del"))
16574         is_add = 0;
16575       else if (unformat (input, "locator-set %s", &ls_name))
16576         ls_name_set = 1;
16577       else
16578         {
16579           errmsg ("parse error '%U'", format_unformat_error, input);
16580           return -99;
16581         }
16582     }
16583
16584   if (!ls_name_set)
16585     {
16586       errmsg ("locator-set name not set!");
16587       return -99;
16588     }
16589
16590   M (ONE_PITR_SET_LOCATOR_SET, mp);
16591
16592   mp->is_add = is_add;
16593   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16594   vec_free (ls_name);
16595
16596   /* send */
16597   S (mp);
16598
16599   /* wait for reply */
16600   W (ret);
16601   return ret;
16602 }
16603
16604 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16605
16606 static int
16607 api_one_nsh_set_locator_set (vat_main_t * vam)
16608 {
16609   u8 ls_name_set = 0;
16610   unformat_input_t *input = vam->input;
16611   vl_api_one_nsh_set_locator_set_t *mp;
16612   u8 is_add = 1;
16613   u8 *ls_name = 0;
16614   int ret;
16615
16616   /* Parse args required to build the message */
16617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (input, "del"))
16620         is_add = 0;
16621       else if (unformat (input, "ls %s", &ls_name))
16622         ls_name_set = 1;
16623       else
16624         {
16625           errmsg ("parse error '%U'", format_unformat_error, input);
16626           return -99;
16627         }
16628     }
16629
16630   if (!ls_name_set && is_add)
16631     {
16632       errmsg ("locator-set name not set!");
16633       return -99;
16634     }
16635
16636   M (ONE_NSH_SET_LOCATOR_SET, mp);
16637
16638   mp->is_add = is_add;
16639   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16640   vec_free (ls_name);
16641
16642   /* send */
16643   S (mp);
16644
16645   /* wait for reply */
16646   W (ret);
16647   return ret;
16648 }
16649
16650 static int
16651 api_show_one_pitr (vat_main_t * vam)
16652 {
16653   vl_api_show_one_pitr_t *mp;
16654   int ret;
16655
16656   if (!vam->json_output)
16657     {
16658       print (vam->ofp, "%=20s", "lisp status:");
16659     }
16660
16661   M (SHOW_ONE_PITR, mp);
16662   /* send it... */
16663   S (mp);
16664
16665   /* Wait for a reply... */
16666   W (ret);
16667   return ret;
16668 }
16669
16670 #define api_show_lisp_pitr api_show_one_pitr
16671
16672 static int
16673 api_one_use_petr (vat_main_t * vam)
16674 {
16675   unformat_input_t *input = vam->input;
16676   vl_api_one_use_petr_t *mp;
16677   u8 is_add = 0;
16678   ip_address_t ip;
16679   int ret;
16680
16681   clib_memset (&ip, 0, sizeof (ip));
16682
16683   /* Parse args required to build the message */
16684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16685     {
16686       if (unformat (input, "disable"))
16687         is_add = 0;
16688       else
16689         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16690         {
16691           is_add = 1;
16692           ip_addr_version (&ip) = IP4;
16693         }
16694       else
16695         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16696         {
16697           is_add = 1;
16698           ip_addr_version (&ip) = IP6;
16699         }
16700       else
16701         {
16702           errmsg ("parse error '%U'", format_unformat_error, input);
16703           return -99;
16704         }
16705     }
16706
16707   M (ONE_USE_PETR, mp);
16708
16709   mp->is_add = is_add;
16710   if (is_add)
16711     {
16712       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16713       if (mp->is_ip4)
16714         clib_memcpy (mp->address, &ip, 4);
16715       else
16716         clib_memcpy (mp->address, &ip, 16);
16717     }
16718
16719   /* send */
16720   S (mp);
16721
16722   /* wait for reply */
16723   W (ret);
16724   return ret;
16725 }
16726
16727 #define api_lisp_use_petr api_one_use_petr
16728
16729 static int
16730 api_show_one_nsh_mapping (vat_main_t * vam)
16731 {
16732   vl_api_show_one_use_petr_t *mp;
16733   int ret;
16734
16735   if (!vam->json_output)
16736     {
16737       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16738     }
16739
16740   M (SHOW_ONE_NSH_MAPPING, mp);
16741   /* send it... */
16742   S (mp);
16743
16744   /* Wait for a reply... */
16745   W (ret);
16746   return ret;
16747 }
16748
16749 static int
16750 api_show_one_use_petr (vat_main_t * vam)
16751 {
16752   vl_api_show_one_use_petr_t *mp;
16753   int ret;
16754
16755   if (!vam->json_output)
16756     {
16757       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16758     }
16759
16760   M (SHOW_ONE_USE_PETR, mp);
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 #define api_show_lisp_use_petr api_show_one_use_petr
16770
16771 /**
16772  * Add/delete mapping between vni and vrf
16773  */
16774 static int
16775 api_one_eid_table_add_del_map (vat_main_t * vam)
16776 {
16777   unformat_input_t *input = vam->input;
16778   vl_api_one_eid_table_add_del_map_t *mp;
16779   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16780   u32 vni, vrf, bd_index;
16781   int ret;
16782
16783   /* Parse args required to build the message */
16784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16785     {
16786       if (unformat (input, "del"))
16787         is_add = 0;
16788       else if (unformat (input, "vrf %d", &vrf))
16789         vrf_set = 1;
16790       else if (unformat (input, "bd_index %d", &bd_index))
16791         bd_index_set = 1;
16792       else if (unformat (input, "vni %d", &vni))
16793         vni_set = 1;
16794       else
16795         break;
16796     }
16797
16798   if (!vni_set || (!vrf_set && !bd_index_set))
16799     {
16800       errmsg ("missing arguments!");
16801       return -99;
16802     }
16803
16804   if (vrf_set && bd_index_set)
16805     {
16806       errmsg ("error: both vrf and bd entered!");
16807       return -99;
16808     }
16809
16810   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16811
16812   mp->is_add = is_add;
16813   mp->vni = htonl (vni);
16814   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16815   mp->is_l2 = bd_index_set;
16816
16817   /* send */
16818   S (mp);
16819
16820   /* wait for reply */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16826
16827 uword
16828 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16829 {
16830   u32 *action = va_arg (*args, u32 *);
16831   u8 *s = 0;
16832
16833   if (unformat (input, "%s", &s))
16834     {
16835       if (!strcmp ((char *) s, "no-action"))
16836         action[0] = 0;
16837       else if (!strcmp ((char *) s, "natively-forward"))
16838         action[0] = 1;
16839       else if (!strcmp ((char *) s, "send-map-request"))
16840         action[0] = 2;
16841       else if (!strcmp ((char *) s, "drop"))
16842         action[0] = 3;
16843       else
16844         {
16845           clib_warning ("invalid action: '%s'", s);
16846           action[0] = 3;
16847         }
16848     }
16849   else
16850     return 0;
16851
16852   vec_free (s);
16853   return 1;
16854 }
16855
16856 /**
16857  * Add/del remote mapping to/from ONE control plane
16858  *
16859  * @param vam vpp API test context
16860  * @return return code
16861  */
16862 static int
16863 api_one_add_del_remote_mapping (vat_main_t * vam)
16864 {
16865   unformat_input_t *input = vam->input;
16866   vl_api_one_add_del_remote_mapping_t *mp;
16867   u32 vni = 0;
16868   lisp_eid_vat_t _eid, *eid = &_eid;
16869   lisp_eid_vat_t _seid, *seid = &_seid;
16870   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16871   u32 action = ~0, p, w, data_len;
16872   ip4_address_t rloc4;
16873   ip6_address_t rloc6;
16874   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16875   int ret;
16876
16877   clib_memset (&rloc, 0, sizeof (rloc));
16878
16879   /* Parse args required to build the message */
16880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16881     {
16882       if (unformat (input, "del-all"))
16883         {
16884           del_all = 1;
16885         }
16886       else if (unformat (input, "del"))
16887         {
16888           is_add = 0;
16889         }
16890       else if (unformat (input, "add"))
16891         {
16892           is_add = 1;
16893         }
16894       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16895         {
16896           eid_set = 1;
16897         }
16898       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16899         {
16900           seid_set = 1;
16901         }
16902       else if (unformat (input, "vni %d", &vni))
16903         {
16904           ;
16905         }
16906       else if (unformat (input, "p %d w %d", &p, &w))
16907         {
16908           if (!curr_rloc)
16909             {
16910               errmsg ("No RLOC configured for setting priority/weight!");
16911               return -99;
16912             }
16913           curr_rloc->priority = p;
16914           curr_rloc->weight = w;
16915         }
16916       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16917         {
16918           rloc.is_ip4 = 1;
16919           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16920           vec_add1 (rlocs, rloc);
16921           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16922         }
16923       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16924         {
16925           rloc.is_ip4 = 0;
16926           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16927           vec_add1 (rlocs, rloc);
16928           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16929         }
16930       else if (unformat (input, "action %U",
16931                          unformat_negative_mapping_action, &action))
16932         {
16933           ;
16934         }
16935       else
16936         {
16937           clib_warning ("parse error '%U'", format_unformat_error, input);
16938           return -99;
16939         }
16940     }
16941
16942   if (0 == eid_set)
16943     {
16944       errmsg ("missing params!");
16945       return -99;
16946     }
16947
16948   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16949     {
16950       errmsg ("no action set for negative map-reply!");
16951       return -99;
16952     }
16953
16954   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16955
16956   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16957   mp->is_add = is_add;
16958   mp->vni = htonl (vni);
16959   mp->action = (u8) action;
16960   mp->is_src_dst = seid_set;
16961   mp->eid_len = eid->len;
16962   mp->seid_len = seid->len;
16963   mp->del_all = del_all;
16964   mp->eid_type = eid->type;
16965   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16966   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16967
16968   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16969   clib_memcpy (mp->rlocs, rlocs, data_len);
16970   vec_free (rlocs);
16971
16972   /* send it... */
16973   S (mp);
16974
16975   /* Wait for a reply... */
16976   W (ret);
16977   return ret;
16978 }
16979
16980 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16981
16982 /**
16983  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16984  * forwarding entries in data-plane accordingly.
16985  *
16986  * @param vam vpp API test context
16987  * @return return code
16988  */
16989 static int
16990 api_one_add_del_adjacency (vat_main_t * vam)
16991 {
16992   unformat_input_t *input = vam->input;
16993   vl_api_one_add_del_adjacency_t *mp;
16994   u32 vni = 0;
16995   ip4_address_t leid4, reid4;
16996   ip6_address_t leid6, reid6;
16997   u8 reid_mac[6] = { 0 };
16998   u8 leid_mac[6] = { 0 };
16999   u8 reid_type, leid_type;
17000   u32 leid_len = 0, reid_len = 0, len;
17001   u8 is_add = 1;
17002   int ret;
17003
17004   leid_type = reid_type = (u8) ~ 0;
17005
17006   /* Parse args required to build the message */
17007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17008     {
17009       if (unformat (input, "del"))
17010         {
17011           is_add = 0;
17012         }
17013       else if (unformat (input, "add"))
17014         {
17015           is_add = 1;
17016         }
17017       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17018                          &reid4, &len))
17019         {
17020           reid_type = 0;        /* ipv4 */
17021           reid_len = len;
17022         }
17023       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17024                          &reid6, &len))
17025         {
17026           reid_type = 1;        /* ipv6 */
17027           reid_len = len;
17028         }
17029       else if (unformat (input, "reid %U", unformat_ethernet_address,
17030                          reid_mac))
17031         {
17032           reid_type = 2;        /* mac */
17033         }
17034       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17035                          &leid4, &len))
17036         {
17037           leid_type = 0;        /* ipv4 */
17038           leid_len = len;
17039         }
17040       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17041                          &leid6, &len))
17042         {
17043           leid_type = 1;        /* ipv6 */
17044           leid_len = len;
17045         }
17046       else if (unformat (input, "leid %U", unformat_ethernet_address,
17047                          leid_mac))
17048         {
17049           leid_type = 2;        /* mac */
17050         }
17051       else if (unformat (input, "vni %d", &vni))
17052         {
17053           ;
17054         }
17055       else
17056         {
17057           errmsg ("parse error '%U'", format_unformat_error, input);
17058           return -99;
17059         }
17060     }
17061
17062   if ((u8) ~ 0 == reid_type)
17063     {
17064       errmsg ("missing params!");
17065       return -99;
17066     }
17067
17068   if (leid_type != reid_type)
17069     {
17070       errmsg ("remote and local EIDs are of different types!");
17071       return -99;
17072     }
17073
17074   M (ONE_ADD_DEL_ADJACENCY, mp);
17075   mp->is_add = is_add;
17076   mp->vni = htonl (vni);
17077   mp->leid_len = leid_len;
17078   mp->reid_len = reid_len;
17079   mp->eid_type = reid_type;
17080
17081   switch (mp->eid_type)
17082     {
17083     case 0:
17084       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17085       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17086       break;
17087     case 1:
17088       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17089       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17090       break;
17091     case 2:
17092       clib_memcpy (mp->leid, leid_mac, 6);
17093       clib_memcpy (mp->reid, reid_mac, 6);
17094       break;
17095     default:
17096       errmsg ("unknown EID type %d!", mp->eid_type);
17097       return 0;
17098     }
17099
17100   /* send it... */
17101   S (mp);
17102
17103   /* Wait for a reply... */
17104   W (ret);
17105   return ret;
17106 }
17107
17108 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17109
17110 uword
17111 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17112 {
17113   u32 *mode = va_arg (*args, u32 *);
17114
17115   if (unformat (input, "lisp"))
17116     *mode = 0;
17117   else if (unformat (input, "vxlan"))
17118     *mode = 1;
17119   else
17120     return 0;
17121
17122   return 1;
17123 }
17124
17125 static int
17126 api_gpe_get_encap_mode (vat_main_t * vam)
17127 {
17128   vl_api_gpe_get_encap_mode_t *mp;
17129   int ret;
17130
17131   /* Construct the API message */
17132   M (GPE_GET_ENCAP_MODE, mp);
17133
17134   /* send it... */
17135   S (mp);
17136
17137   /* Wait for a reply... */
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static int
17143 api_gpe_set_encap_mode (vat_main_t * vam)
17144 {
17145   unformat_input_t *input = vam->input;
17146   vl_api_gpe_set_encap_mode_t *mp;
17147   int ret;
17148   u32 mode = 0;
17149
17150   /* Parse args required to build the message */
17151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17152     {
17153       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17154         ;
17155       else
17156         break;
17157     }
17158
17159   /* Construct the API message */
17160   M (GPE_SET_ENCAP_MODE, mp);
17161
17162   mp->mode = mode;
17163
17164   /* send it... */
17165   S (mp);
17166
17167   /* Wait for a reply... */
17168   W (ret);
17169   return ret;
17170 }
17171
17172 static int
17173 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17174 {
17175   unformat_input_t *input = vam->input;
17176   vl_api_gpe_add_del_iface_t *mp;
17177   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17178   u32 dp_table = 0, vni = 0;
17179   int ret;
17180
17181   /* Parse args required to build the message */
17182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17183     {
17184       if (unformat (input, "up"))
17185         {
17186           action_set = 1;
17187           is_add = 1;
17188         }
17189       else if (unformat (input, "down"))
17190         {
17191           action_set = 1;
17192           is_add = 0;
17193         }
17194       else if (unformat (input, "table_id %d", &dp_table))
17195         {
17196           dp_table_set = 1;
17197         }
17198       else if (unformat (input, "bd_id %d", &dp_table))
17199         {
17200           dp_table_set = 1;
17201           is_l2 = 1;
17202         }
17203       else if (unformat (input, "vni %d", &vni))
17204         {
17205           vni_set = 1;
17206         }
17207       else
17208         break;
17209     }
17210
17211   if (action_set == 0)
17212     {
17213       errmsg ("Action not set");
17214       return -99;
17215     }
17216   if (dp_table_set == 0 || vni_set == 0)
17217     {
17218       errmsg ("vni and dp_table must be set");
17219       return -99;
17220     }
17221
17222   /* Construct the API message */
17223   M (GPE_ADD_DEL_IFACE, mp);
17224
17225   mp->is_add = is_add;
17226   mp->dp_table = clib_host_to_net_u32 (dp_table);
17227   mp->is_l2 = is_l2;
17228   mp->vni = clib_host_to_net_u32 (vni);
17229
17230   /* send it... */
17231   S (mp);
17232
17233   /* Wait for a reply... */
17234   W (ret);
17235   return ret;
17236 }
17237
17238 static int
17239 api_one_map_register_fallback_threshold (vat_main_t * vam)
17240 {
17241   unformat_input_t *input = vam->input;
17242   vl_api_one_map_register_fallback_threshold_t *mp;
17243   u32 value = 0;
17244   u8 is_set = 0;
17245   int ret;
17246
17247   /* Parse args required to build the message */
17248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17249     {
17250       if (unformat (input, "%u", &value))
17251         is_set = 1;
17252       else
17253         {
17254           clib_warning ("parse error '%U'", format_unformat_error, input);
17255           return -99;
17256         }
17257     }
17258
17259   if (!is_set)
17260     {
17261       errmsg ("fallback threshold value is missing!");
17262       return -99;
17263     }
17264
17265   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17266   mp->value = clib_host_to_net_u32 (value);
17267
17268   /* send it... */
17269   S (mp);
17270
17271   /* Wait for a reply... */
17272   W (ret);
17273   return ret;
17274 }
17275
17276 static int
17277 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17278 {
17279   vl_api_show_one_map_register_fallback_threshold_t *mp;
17280   int ret;
17281
17282   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17283
17284   /* send it... */
17285   S (mp);
17286
17287   /* Wait for a reply... */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 uword
17293 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17294 {
17295   u32 *proto = va_arg (*args, u32 *);
17296
17297   if (unformat (input, "udp"))
17298     *proto = 1;
17299   else if (unformat (input, "api"))
17300     *proto = 2;
17301   else
17302     return 0;
17303
17304   return 1;
17305 }
17306
17307 static int
17308 api_one_set_transport_protocol (vat_main_t * vam)
17309 {
17310   unformat_input_t *input = vam->input;
17311   vl_api_one_set_transport_protocol_t *mp;
17312   u8 is_set = 0;
17313   u32 protocol = 0;
17314   int ret;
17315
17316   /* Parse args required to build the message */
17317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17318     {
17319       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17320         is_set = 1;
17321       else
17322         {
17323           clib_warning ("parse error '%U'", format_unformat_error, input);
17324           return -99;
17325         }
17326     }
17327
17328   if (!is_set)
17329     {
17330       errmsg ("Transport protocol missing!");
17331       return -99;
17332     }
17333
17334   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17335   mp->protocol = (u8) protocol;
17336
17337   /* send it... */
17338   S (mp);
17339
17340   /* Wait for a reply... */
17341   W (ret);
17342   return ret;
17343 }
17344
17345 static int
17346 api_one_get_transport_protocol (vat_main_t * vam)
17347 {
17348   vl_api_one_get_transport_protocol_t *mp;
17349   int ret;
17350
17351   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17352
17353   /* send it... */
17354   S (mp);
17355
17356   /* Wait for a reply... */
17357   W (ret);
17358   return ret;
17359 }
17360
17361 static int
17362 api_one_map_register_set_ttl (vat_main_t * vam)
17363 {
17364   unformat_input_t *input = vam->input;
17365   vl_api_one_map_register_set_ttl_t *mp;
17366   u32 ttl = 0;
17367   u8 is_set = 0;
17368   int ret;
17369
17370   /* Parse args required to build the message */
17371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17372     {
17373       if (unformat (input, "%u", &ttl))
17374         is_set = 1;
17375       else
17376         {
17377           clib_warning ("parse error '%U'", format_unformat_error, input);
17378           return -99;
17379         }
17380     }
17381
17382   if (!is_set)
17383     {
17384       errmsg ("TTL value missing!");
17385       return -99;
17386     }
17387
17388   M (ONE_MAP_REGISTER_SET_TTL, mp);
17389   mp->ttl = clib_host_to_net_u32 (ttl);
17390
17391   /* send it... */
17392   S (mp);
17393
17394   /* Wait for a reply... */
17395   W (ret);
17396   return ret;
17397 }
17398
17399 static int
17400 api_show_one_map_register_ttl (vat_main_t * vam)
17401 {
17402   vl_api_show_one_map_register_ttl_t *mp;
17403   int ret;
17404
17405   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17406
17407   /* send it... */
17408   S (mp);
17409
17410   /* Wait for a reply... */
17411   W (ret);
17412   return ret;
17413 }
17414
17415 /**
17416  * Add/del map request itr rlocs from ONE control plane and updates
17417  *
17418  * @param vam vpp API test context
17419  * @return return code
17420  */
17421 static int
17422 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17423 {
17424   unformat_input_t *input = vam->input;
17425   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17426   u8 *locator_set_name = 0;
17427   u8 locator_set_name_set = 0;
17428   u8 is_add = 1;
17429   int ret;
17430
17431   /* Parse args required to build the message */
17432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17433     {
17434       if (unformat (input, "del"))
17435         {
17436           is_add = 0;
17437         }
17438       else if (unformat (input, "%_%v%_", &locator_set_name))
17439         {
17440           locator_set_name_set = 1;
17441         }
17442       else
17443         {
17444           clib_warning ("parse error '%U'", format_unformat_error, input);
17445           return -99;
17446         }
17447     }
17448
17449   if (is_add && !locator_set_name_set)
17450     {
17451       errmsg ("itr-rloc is not set!");
17452       return -99;
17453     }
17454
17455   if (is_add && vec_len (locator_set_name) > 64)
17456     {
17457       errmsg ("itr-rloc locator-set name too long");
17458       vec_free (locator_set_name);
17459       return -99;
17460     }
17461
17462   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17463   mp->is_add = is_add;
17464   if (is_add)
17465     {
17466       clib_memcpy (mp->locator_set_name, locator_set_name,
17467                    vec_len (locator_set_name));
17468     }
17469   else
17470     {
17471       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17472     }
17473   vec_free (locator_set_name);
17474
17475   /* send it... */
17476   S (mp);
17477
17478   /* Wait for a reply... */
17479   W (ret);
17480   return ret;
17481 }
17482
17483 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17484
17485 static int
17486 api_one_locator_dump (vat_main_t * vam)
17487 {
17488   unformat_input_t *input = vam->input;
17489   vl_api_one_locator_dump_t *mp;
17490   vl_api_control_ping_t *mp_ping;
17491   u8 is_index_set = 0, is_name_set = 0;
17492   u8 *ls_name = 0;
17493   u32 ls_index = ~0;
17494   int ret;
17495
17496   /* Parse args required to build the message */
17497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17498     {
17499       if (unformat (input, "ls_name %_%v%_", &ls_name))
17500         {
17501           is_name_set = 1;
17502         }
17503       else if (unformat (input, "ls_index %d", &ls_index))
17504         {
17505           is_index_set = 1;
17506         }
17507       else
17508         {
17509           errmsg ("parse error '%U'", format_unformat_error, input);
17510           return -99;
17511         }
17512     }
17513
17514   if (!is_index_set && !is_name_set)
17515     {
17516       errmsg ("error: expected one of index or name!");
17517       return -99;
17518     }
17519
17520   if (is_index_set && is_name_set)
17521     {
17522       errmsg ("error: only one param expected!");
17523       return -99;
17524     }
17525
17526   if (vec_len (ls_name) > 62)
17527     {
17528       errmsg ("error: locator set name too long!");
17529       return -99;
17530     }
17531
17532   if (!vam->json_output)
17533     {
17534       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17535     }
17536
17537   M (ONE_LOCATOR_DUMP, mp);
17538   mp->is_index_set = is_index_set;
17539
17540   if (is_index_set)
17541     mp->ls_index = clib_host_to_net_u32 (ls_index);
17542   else
17543     {
17544       vec_add1 (ls_name, 0);
17545       strncpy ((char *) mp->ls_name, (char *) ls_name,
17546                sizeof (mp->ls_name) - 1);
17547     }
17548
17549   /* send it... */
17550   S (mp);
17551
17552   /* Use a control ping for synchronization */
17553   MPING (CONTROL_PING, mp_ping);
17554   S (mp_ping);
17555
17556   /* Wait for a reply... */
17557   W (ret);
17558   return ret;
17559 }
17560
17561 #define api_lisp_locator_dump api_one_locator_dump
17562
17563 static int
17564 api_one_locator_set_dump (vat_main_t * vam)
17565 {
17566   vl_api_one_locator_set_dump_t *mp;
17567   vl_api_control_ping_t *mp_ping;
17568   unformat_input_t *input = vam->input;
17569   u8 filter = 0;
17570   int ret;
17571
17572   /* Parse args required to build the message */
17573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17574     {
17575       if (unformat (input, "local"))
17576         {
17577           filter = 1;
17578         }
17579       else if (unformat (input, "remote"))
17580         {
17581           filter = 2;
17582         }
17583       else
17584         {
17585           errmsg ("parse error '%U'", format_unformat_error, input);
17586           return -99;
17587         }
17588     }
17589
17590   if (!vam->json_output)
17591     {
17592       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17593     }
17594
17595   M (ONE_LOCATOR_SET_DUMP, mp);
17596
17597   mp->filter = filter;
17598
17599   /* send it... */
17600   S (mp);
17601
17602   /* Use a control ping for synchronization */
17603   MPING (CONTROL_PING, mp_ping);
17604   S (mp_ping);
17605
17606   /* Wait for a reply... */
17607   W (ret);
17608   return ret;
17609 }
17610
17611 #define api_lisp_locator_set_dump api_one_locator_set_dump
17612
17613 static int
17614 api_one_eid_table_map_dump (vat_main_t * vam)
17615 {
17616   u8 is_l2 = 0;
17617   u8 mode_set = 0;
17618   unformat_input_t *input = vam->input;
17619   vl_api_one_eid_table_map_dump_t *mp;
17620   vl_api_control_ping_t *mp_ping;
17621   int ret;
17622
17623   /* Parse args required to build the message */
17624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17625     {
17626       if (unformat (input, "l2"))
17627         {
17628           is_l2 = 1;
17629           mode_set = 1;
17630         }
17631       else if (unformat (input, "l3"))
17632         {
17633           is_l2 = 0;
17634           mode_set = 1;
17635         }
17636       else
17637         {
17638           errmsg ("parse error '%U'", format_unformat_error, input);
17639           return -99;
17640         }
17641     }
17642
17643   if (!mode_set)
17644     {
17645       errmsg ("expected one of 'l2' or 'l3' parameter!");
17646       return -99;
17647     }
17648
17649   if (!vam->json_output)
17650     {
17651       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17652     }
17653
17654   M (ONE_EID_TABLE_MAP_DUMP, mp);
17655   mp->is_l2 = is_l2;
17656
17657   /* send it... */
17658   S (mp);
17659
17660   /* Use a control ping for synchronization */
17661   MPING (CONTROL_PING, mp_ping);
17662   S (mp_ping);
17663
17664   /* Wait for a reply... */
17665   W (ret);
17666   return ret;
17667 }
17668
17669 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17670
17671 static int
17672 api_one_eid_table_vni_dump (vat_main_t * vam)
17673 {
17674   vl_api_one_eid_table_vni_dump_t *mp;
17675   vl_api_control_ping_t *mp_ping;
17676   int ret;
17677
17678   if (!vam->json_output)
17679     {
17680       print (vam->ofp, "VNI");
17681     }
17682
17683   M (ONE_EID_TABLE_VNI_DUMP, mp);
17684
17685   /* send it... */
17686   S (mp);
17687
17688   /* Use a control ping for synchronization */
17689   MPING (CONTROL_PING, mp_ping);
17690   S (mp_ping);
17691
17692   /* Wait for a reply... */
17693   W (ret);
17694   return ret;
17695 }
17696
17697 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17698
17699 static int
17700 api_one_eid_table_dump (vat_main_t * vam)
17701 {
17702   unformat_input_t *i = vam->input;
17703   vl_api_one_eid_table_dump_t *mp;
17704   vl_api_control_ping_t *mp_ping;
17705   struct in_addr ip4;
17706   struct in6_addr ip6;
17707   u8 mac[6];
17708   u8 eid_type = ~0, eid_set = 0;
17709   u32 prefix_length = ~0, t, vni = 0;
17710   u8 filter = 0;
17711   int ret;
17712   lisp_nsh_api_t nsh;
17713
17714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17715     {
17716       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17717         {
17718           eid_set = 1;
17719           eid_type = 0;
17720           prefix_length = t;
17721         }
17722       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17723         {
17724           eid_set = 1;
17725           eid_type = 1;
17726           prefix_length = t;
17727         }
17728       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17729         {
17730           eid_set = 1;
17731           eid_type = 2;
17732         }
17733       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17734         {
17735           eid_set = 1;
17736           eid_type = 3;
17737         }
17738       else if (unformat (i, "vni %d", &t))
17739         {
17740           vni = t;
17741         }
17742       else if (unformat (i, "local"))
17743         {
17744           filter = 1;
17745         }
17746       else if (unformat (i, "remote"))
17747         {
17748           filter = 2;
17749         }
17750       else
17751         {
17752           errmsg ("parse error '%U'", format_unformat_error, i);
17753           return -99;
17754         }
17755     }
17756
17757   if (!vam->json_output)
17758     {
17759       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17760              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17761     }
17762
17763   M (ONE_EID_TABLE_DUMP, mp);
17764
17765   mp->filter = filter;
17766   if (eid_set)
17767     {
17768       mp->eid_set = 1;
17769       mp->vni = htonl (vni);
17770       mp->eid_type = eid_type;
17771       switch (eid_type)
17772         {
17773         case 0:
17774           mp->prefix_length = prefix_length;
17775           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17776           break;
17777         case 1:
17778           mp->prefix_length = prefix_length;
17779           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17780           break;
17781         case 2:
17782           clib_memcpy (mp->eid, mac, sizeof (mac));
17783           break;
17784         case 3:
17785           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17786           break;
17787         default:
17788           errmsg ("unknown EID type %d!", eid_type);
17789           return -99;
17790         }
17791     }
17792
17793   /* send it... */
17794   S (mp);
17795
17796   /* Use a control ping for synchronization */
17797   MPING (CONTROL_PING, mp_ping);
17798   S (mp_ping);
17799
17800   /* Wait for a reply... */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_lisp_eid_table_dump api_one_eid_table_dump
17806
17807 static int
17808 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17809 {
17810   unformat_input_t *i = vam->input;
17811   vl_api_gpe_fwd_entries_get_t *mp;
17812   u8 vni_set = 0;
17813   u32 vni = ~0;
17814   int ret;
17815
17816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17817     {
17818       if (unformat (i, "vni %d", &vni))
17819         {
17820           vni_set = 1;
17821         }
17822       else
17823         {
17824           errmsg ("parse error '%U'", format_unformat_error, i);
17825           return -99;
17826         }
17827     }
17828
17829   if (!vni_set)
17830     {
17831       errmsg ("vni not set!");
17832       return -99;
17833     }
17834
17835   if (!vam->json_output)
17836     {
17837       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17838              "leid", "reid");
17839     }
17840
17841   M (GPE_FWD_ENTRIES_GET, mp);
17842   mp->vni = clib_host_to_net_u32 (vni);
17843
17844   /* send it... */
17845   S (mp);
17846
17847   /* Wait for a reply... */
17848   W (ret);
17849   return ret;
17850 }
17851
17852 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17853 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17854 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17855 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17856 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17857 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17858 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17859 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17860
17861 static int
17862 api_one_adjacencies_get (vat_main_t * vam)
17863 {
17864   unformat_input_t *i = vam->input;
17865   vl_api_one_adjacencies_get_t *mp;
17866   u8 vni_set = 0;
17867   u32 vni = ~0;
17868   int ret;
17869
17870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17871     {
17872       if (unformat (i, "vni %d", &vni))
17873         {
17874           vni_set = 1;
17875         }
17876       else
17877         {
17878           errmsg ("parse error '%U'", format_unformat_error, i);
17879           return -99;
17880         }
17881     }
17882
17883   if (!vni_set)
17884     {
17885       errmsg ("vni not set!");
17886       return -99;
17887     }
17888
17889   if (!vam->json_output)
17890     {
17891       print (vam->ofp, "%s %40s", "leid", "reid");
17892     }
17893
17894   M (ONE_ADJACENCIES_GET, mp);
17895   mp->vni = clib_host_to_net_u32 (vni);
17896
17897   /* send it... */
17898   S (mp);
17899
17900   /* Wait for a reply... */
17901   W (ret);
17902   return ret;
17903 }
17904
17905 #define api_lisp_adjacencies_get api_one_adjacencies_get
17906
17907 static int
17908 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17909 {
17910   unformat_input_t *i = vam->input;
17911   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17912   int ret;
17913   u8 ip_family_set = 0, is_ip4 = 1;
17914
17915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17916     {
17917       if (unformat (i, "ip4"))
17918         {
17919           ip_family_set = 1;
17920           is_ip4 = 1;
17921         }
17922       else if (unformat (i, "ip6"))
17923         {
17924           ip_family_set = 1;
17925           is_ip4 = 0;
17926         }
17927       else
17928         {
17929           errmsg ("parse error '%U'", format_unformat_error, i);
17930           return -99;
17931         }
17932     }
17933
17934   if (!ip_family_set)
17935     {
17936       errmsg ("ip family not set!");
17937       return -99;
17938     }
17939
17940   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17941   mp->is_ip4 = is_ip4;
17942
17943   /* send it... */
17944   S (mp);
17945
17946   /* Wait for a reply... */
17947   W (ret);
17948   return ret;
17949 }
17950
17951 static int
17952 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17953 {
17954   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17955   int ret;
17956
17957   if (!vam->json_output)
17958     {
17959       print (vam->ofp, "VNIs");
17960     }
17961
17962   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17963
17964   /* send it... */
17965   S (mp);
17966
17967   /* Wait for a reply... */
17968   W (ret);
17969   return ret;
17970 }
17971
17972 static int
17973 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17974 {
17975   unformat_input_t *i = vam->input;
17976   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17977   int ret = 0;
17978   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17979   struct in_addr ip4;
17980   struct in6_addr ip6;
17981   u32 table_id = 0, nh_sw_if_index = ~0;
17982
17983   clib_memset (&ip4, 0, sizeof (ip4));
17984   clib_memset (&ip6, 0, sizeof (ip6));
17985
17986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17987     {
17988       if (unformat (i, "del"))
17989         is_add = 0;
17990       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17991                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17992         {
17993           ip_set = 1;
17994           is_ip4 = 1;
17995         }
17996       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17997                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17998         {
17999           ip_set = 1;
18000           is_ip4 = 0;
18001         }
18002       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18003         {
18004           ip_set = 1;
18005           is_ip4 = 1;
18006           nh_sw_if_index = ~0;
18007         }
18008       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18009         {
18010           ip_set = 1;
18011           is_ip4 = 0;
18012           nh_sw_if_index = ~0;
18013         }
18014       else if (unformat (i, "table %d", &table_id))
18015         ;
18016       else
18017         {
18018           errmsg ("parse error '%U'", format_unformat_error, i);
18019           return -99;
18020         }
18021     }
18022
18023   if (!ip_set)
18024     {
18025       errmsg ("nh addr not set!");
18026       return -99;
18027     }
18028
18029   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18030   mp->is_add = is_add;
18031   mp->table_id = clib_host_to_net_u32 (table_id);
18032   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18033   mp->is_ip4 = is_ip4;
18034   if (is_ip4)
18035     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18036   else
18037     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18038
18039   /* send it... */
18040   S (mp);
18041
18042   /* Wait for a reply... */
18043   W (ret);
18044   return ret;
18045 }
18046
18047 static int
18048 api_one_map_server_dump (vat_main_t * vam)
18049 {
18050   vl_api_one_map_server_dump_t *mp;
18051   vl_api_control_ping_t *mp_ping;
18052   int ret;
18053
18054   if (!vam->json_output)
18055     {
18056       print (vam->ofp, "%=20s", "Map server");
18057     }
18058
18059   M (ONE_MAP_SERVER_DUMP, mp);
18060   /* send it... */
18061   S (mp);
18062
18063   /* Use a control ping for synchronization */
18064   MPING (CONTROL_PING, mp_ping);
18065   S (mp_ping);
18066
18067   /* Wait for a reply... */
18068   W (ret);
18069   return ret;
18070 }
18071
18072 #define api_lisp_map_server_dump api_one_map_server_dump
18073
18074 static int
18075 api_one_map_resolver_dump (vat_main_t * vam)
18076 {
18077   vl_api_one_map_resolver_dump_t *mp;
18078   vl_api_control_ping_t *mp_ping;
18079   int ret;
18080
18081   if (!vam->json_output)
18082     {
18083       print (vam->ofp, "%=20s", "Map resolver");
18084     }
18085
18086   M (ONE_MAP_RESOLVER_DUMP, mp);
18087   /* send it... */
18088   S (mp);
18089
18090   /* Use a control ping for synchronization */
18091   MPING (CONTROL_PING, mp_ping);
18092   S (mp_ping);
18093
18094   /* Wait for a reply... */
18095   W (ret);
18096   return ret;
18097 }
18098
18099 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18100
18101 static int
18102 api_one_stats_flush (vat_main_t * vam)
18103 {
18104   vl_api_one_stats_flush_t *mp;
18105   int ret = 0;
18106
18107   M (ONE_STATS_FLUSH, mp);
18108   S (mp);
18109   W (ret);
18110   return ret;
18111 }
18112
18113 static int
18114 api_one_stats_dump (vat_main_t * vam)
18115 {
18116   vl_api_one_stats_dump_t *mp;
18117   vl_api_control_ping_t *mp_ping;
18118   int ret;
18119
18120   M (ONE_STATS_DUMP, mp);
18121   /* send it... */
18122   S (mp);
18123
18124   /* Use a control ping for synchronization */
18125   MPING (CONTROL_PING, mp_ping);
18126   S (mp_ping);
18127
18128   /* Wait for a reply... */
18129   W (ret);
18130   return ret;
18131 }
18132
18133 static int
18134 api_show_one_status (vat_main_t * vam)
18135 {
18136   vl_api_show_one_status_t *mp;
18137   int ret;
18138
18139   if (!vam->json_output)
18140     {
18141       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18142     }
18143
18144   M (SHOW_ONE_STATUS, mp);
18145   /* send it... */
18146   S (mp);
18147   /* Wait for a reply... */
18148   W (ret);
18149   return ret;
18150 }
18151
18152 #define api_show_lisp_status api_show_one_status
18153
18154 static int
18155 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18156 {
18157   vl_api_gpe_fwd_entry_path_dump_t *mp;
18158   vl_api_control_ping_t *mp_ping;
18159   unformat_input_t *i = vam->input;
18160   u32 fwd_entry_index = ~0;
18161   int ret;
18162
18163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18164     {
18165       if (unformat (i, "index %d", &fwd_entry_index))
18166         ;
18167       else
18168         break;
18169     }
18170
18171   if (~0 == fwd_entry_index)
18172     {
18173       errmsg ("no index specified!");
18174       return -99;
18175     }
18176
18177   if (!vam->json_output)
18178     {
18179       print (vam->ofp, "first line");
18180     }
18181
18182   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18183
18184   /* send it... */
18185   S (mp);
18186   /* Use a control ping for synchronization */
18187   MPING (CONTROL_PING, mp_ping);
18188   S (mp_ping);
18189
18190   /* Wait for a reply... */
18191   W (ret);
18192   return ret;
18193 }
18194
18195 static int
18196 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18197 {
18198   vl_api_one_get_map_request_itr_rlocs_t *mp;
18199   int ret;
18200
18201   if (!vam->json_output)
18202     {
18203       print (vam->ofp, "%=20s", "itr-rlocs:");
18204     }
18205
18206   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18207   /* send it... */
18208   S (mp);
18209   /* Wait for a reply... */
18210   W (ret);
18211   return ret;
18212 }
18213
18214 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18215
18216 static int
18217 api_af_packet_create (vat_main_t * vam)
18218 {
18219   unformat_input_t *i = vam->input;
18220   vl_api_af_packet_create_t *mp;
18221   u8 *host_if_name = 0;
18222   u8 hw_addr[6];
18223   u8 random_hw_addr = 1;
18224   int ret;
18225
18226   clib_memset (hw_addr, 0, sizeof (hw_addr));
18227
18228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18229     {
18230       if (unformat (i, "name %s", &host_if_name))
18231         vec_add1 (host_if_name, 0);
18232       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18233         random_hw_addr = 0;
18234       else
18235         break;
18236     }
18237
18238   if (!vec_len (host_if_name))
18239     {
18240       errmsg ("host-interface name must be specified");
18241       return -99;
18242     }
18243
18244   if (vec_len (host_if_name) > 64)
18245     {
18246       errmsg ("host-interface name too long");
18247       return -99;
18248     }
18249
18250   M (AF_PACKET_CREATE, mp);
18251
18252   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18253   clib_memcpy (mp->hw_addr, hw_addr, 6);
18254   mp->use_random_hw_addr = random_hw_addr;
18255   vec_free (host_if_name);
18256
18257   S (mp);
18258
18259   /* *INDENT-OFF* */
18260   W2 (ret,
18261       ({
18262         if (ret == 0)
18263           fprintf (vam->ofp ? vam->ofp : stderr,
18264                    " new sw_if_index = %d\n", vam->sw_if_index);
18265       }));
18266   /* *INDENT-ON* */
18267   return ret;
18268 }
18269
18270 static int
18271 api_af_packet_delete (vat_main_t * vam)
18272 {
18273   unformat_input_t *i = vam->input;
18274   vl_api_af_packet_delete_t *mp;
18275   u8 *host_if_name = 0;
18276   int ret;
18277
18278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18279     {
18280       if (unformat (i, "name %s", &host_if_name))
18281         vec_add1 (host_if_name, 0);
18282       else
18283         break;
18284     }
18285
18286   if (!vec_len (host_if_name))
18287     {
18288       errmsg ("host-interface name must be specified");
18289       return -99;
18290     }
18291
18292   if (vec_len (host_if_name) > 64)
18293     {
18294       errmsg ("host-interface name too long");
18295       return -99;
18296     }
18297
18298   M (AF_PACKET_DELETE, mp);
18299
18300   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18301   vec_free (host_if_name);
18302
18303   S (mp);
18304   W (ret);
18305   return ret;
18306 }
18307
18308 static void vl_api_af_packet_details_t_handler
18309   (vl_api_af_packet_details_t * mp)
18310 {
18311   vat_main_t *vam = &vat_main;
18312
18313   print (vam->ofp, "%-16s %d",
18314          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18315 }
18316
18317 static void vl_api_af_packet_details_t_handler_json
18318   (vl_api_af_packet_details_t * mp)
18319 {
18320   vat_main_t *vam = &vat_main;
18321   vat_json_node_t *node = NULL;
18322
18323   if (VAT_JSON_ARRAY != vam->json_tree.type)
18324     {
18325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18326       vat_json_init_array (&vam->json_tree);
18327     }
18328   node = vat_json_array_add (&vam->json_tree);
18329
18330   vat_json_init_object (node);
18331   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18332   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18333 }
18334
18335 static int
18336 api_af_packet_dump (vat_main_t * vam)
18337 {
18338   vl_api_af_packet_dump_t *mp;
18339   vl_api_control_ping_t *mp_ping;
18340   int ret;
18341
18342   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18343   /* Get list of tap interfaces */
18344   M (AF_PACKET_DUMP, mp);
18345   S (mp);
18346
18347   /* Use a control ping for synchronization */
18348   MPING (CONTROL_PING, mp_ping);
18349   S (mp_ping);
18350
18351   W (ret);
18352   return ret;
18353 }
18354
18355 static int
18356 api_policer_add_del (vat_main_t * vam)
18357 {
18358   unformat_input_t *i = vam->input;
18359   vl_api_policer_add_del_t *mp;
18360   u8 is_add = 1;
18361   u8 *name = 0;
18362   u32 cir = 0;
18363   u32 eir = 0;
18364   u64 cb = 0;
18365   u64 eb = 0;
18366   u8 rate_type = 0;
18367   u8 round_type = 0;
18368   u8 type = 0;
18369   u8 color_aware = 0;
18370   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18371   int ret;
18372
18373   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18374   conform_action.dscp = 0;
18375   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18376   exceed_action.dscp = 0;
18377   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18378   violate_action.dscp = 0;
18379
18380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18381     {
18382       if (unformat (i, "del"))
18383         is_add = 0;
18384       else if (unformat (i, "name %s", &name))
18385         vec_add1 (name, 0);
18386       else if (unformat (i, "cir %u", &cir))
18387         ;
18388       else if (unformat (i, "eir %u", &eir))
18389         ;
18390       else if (unformat (i, "cb %u", &cb))
18391         ;
18392       else if (unformat (i, "eb %u", &eb))
18393         ;
18394       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18395                          &rate_type))
18396         ;
18397       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18398                          &round_type))
18399         ;
18400       else if (unformat (i, "type %U", unformat_policer_type, &type))
18401         ;
18402       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18403                          &conform_action))
18404         ;
18405       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18406                          &exceed_action))
18407         ;
18408       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18409                          &violate_action))
18410         ;
18411       else if (unformat (i, "color-aware"))
18412         color_aware = 1;
18413       else
18414         break;
18415     }
18416
18417   if (!vec_len (name))
18418     {
18419       errmsg ("policer name must be specified");
18420       return -99;
18421     }
18422
18423   if (vec_len (name) > 64)
18424     {
18425       errmsg ("policer name too long");
18426       return -99;
18427     }
18428
18429   M (POLICER_ADD_DEL, mp);
18430
18431   clib_memcpy (mp->name, name, vec_len (name));
18432   vec_free (name);
18433   mp->is_add = is_add;
18434   mp->cir = ntohl (cir);
18435   mp->eir = ntohl (eir);
18436   mp->cb = clib_net_to_host_u64 (cb);
18437   mp->eb = clib_net_to_host_u64 (eb);
18438   mp->rate_type = rate_type;
18439   mp->round_type = round_type;
18440   mp->type = type;
18441   mp->conform_action_type = conform_action.action_type;
18442   mp->conform_dscp = conform_action.dscp;
18443   mp->exceed_action_type = exceed_action.action_type;
18444   mp->exceed_dscp = exceed_action.dscp;
18445   mp->violate_action_type = violate_action.action_type;
18446   mp->violate_dscp = violate_action.dscp;
18447   mp->color_aware = color_aware;
18448
18449   S (mp);
18450   W (ret);
18451   return ret;
18452 }
18453
18454 static int
18455 api_policer_dump (vat_main_t * vam)
18456 {
18457   unformat_input_t *i = vam->input;
18458   vl_api_policer_dump_t *mp;
18459   vl_api_control_ping_t *mp_ping;
18460   u8 *match_name = 0;
18461   u8 match_name_valid = 0;
18462   int ret;
18463
18464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18465     {
18466       if (unformat (i, "name %s", &match_name))
18467         {
18468           vec_add1 (match_name, 0);
18469           match_name_valid = 1;
18470         }
18471       else
18472         break;
18473     }
18474
18475   M (POLICER_DUMP, mp);
18476   mp->match_name_valid = match_name_valid;
18477   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18478   vec_free (match_name);
18479   /* send it... */
18480   S (mp);
18481
18482   /* Use a control ping for synchronization */
18483   MPING (CONTROL_PING, mp_ping);
18484   S (mp_ping);
18485
18486   /* Wait for a reply... */
18487   W (ret);
18488   return ret;
18489 }
18490
18491 static int
18492 api_policer_classify_set_interface (vat_main_t * vam)
18493 {
18494   unformat_input_t *i = vam->input;
18495   vl_api_policer_classify_set_interface_t *mp;
18496   u32 sw_if_index;
18497   int sw_if_index_set;
18498   u32 ip4_table_index = ~0;
18499   u32 ip6_table_index = ~0;
18500   u32 l2_table_index = ~0;
18501   u8 is_add = 1;
18502   int ret;
18503
18504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18505     {
18506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18507         sw_if_index_set = 1;
18508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18509         sw_if_index_set = 1;
18510       else if (unformat (i, "del"))
18511         is_add = 0;
18512       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18513         ;
18514       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18515         ;
18516       else if (unformat (i, "l2-table %d", &l2_table_index))
18517         ;
18518       else
18519         {
18520           clib_warning ("parse error '%U'", format_unformat_error, i);
18521           return -99;
18522         }
18523     }
18524
18525   if (sw_if_index_set == 0)
18526     {
18527       errmsg ("missing interface name or sw_if_index");
18528       return -99;
18529     }
18530
18531   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18532
18533   mp->sw_if_index = ntohl (sw_if_index);
18534   mp->ip4_table_index = ntohl (ip4_table_index);
18535   mp->ip6_table_index = ntohl (ip6_table_index);
18536   mp->l2_table_index = ntohl (l2_table_index);
18537   mp->is_add = is_add;
18538
18539   S (mp);
18540   W (ret);
18541   return ret;
18542 }
18543
18544 static int
18545 api_policer_classify_dump (vat_main_t * vam)
18546 {
18547   unformat_input_t *i = vam->input;
18548   vl_api_policer_classify_dump_t *mp;
18549   vl_api_control_ping_t *mp_ping;
18550   u8 type = POLICER_CLASSIFY_N_TABLES;
18551   int ret;
18552
18553   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18554     ;
18555   else
18556     {
18557       errmsg ("classify table type must be specified");
18558       return -99;
18559     }
18560
18561   if (!vam->json_output)
18562     {
18563       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18564     }
18565
18566   M (POLICER_CLASSIFY_DUMP, mp);
18567   mp->type = type;
18568   /* send it... */
18569   S (mp);
18570
18571   /* Use a control ping for synchronization */
18572   MPING (CONTROL_PING, mp_ping);
18573   S (mp_ping);
18574
18575   /* Wait for a reply... */
18576   W (ret);
18577   return ret;
18578 }
18579
18580 static int
18581 api_netmap_create (vat_main_t * vam)
18582 {
18583   unformat_input_t *i = vam->input;
18584   vl_api_netmap_create_t *mp;
18585   u8 *if_name = 0;
18586   u8 hw_addr[6];
18587   u8 random_hw_addr = 1;
18588   u8 is_pipe = 0;
18589   u8 is_master = 0;
18590   int ret;
18591
18592   clib_memset (hw_addr, 0, sizeof (hw_addr));
18593
18594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18595     {
18596       if (unformat (i, "name %s", &if_name))
18597         vec_add1 (if_name, 0);
18598       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18599         random_hw_addr = 0;
18600       else if (unformat (i, "pipe"))
18601         is_pipe = 1;
18602       else if (unformat (i, "master"))
18603         is_master = 1;
18604       else if (unformat (i, "slave"))
18605         is_master = 0;
18606       else
18607         break;
18608     }
18609
18610   if (!vec_len (if_name))
18611     {
18612       errmsg ("interface name must be specified");
18613       return -99;
18614     }
18615
18616   if (vec_len (if_name) > 64)
18617     {
18618       errmsg ("interface name too long");
18619       return -99;
18620     }
18621
18622   M (NETMAP_CREATE, mp);
18623
18624   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18625   clib_memcpy (mp->hw_addr, hw_addr, 6);
18626   mp->use_random_hw_addr = random_hw_addr;
18627   mp->is_pipe = is_pipe;
18628   mp->is_master = is_master;
18629   vec_free (if_name);
18630
18631   S (mp);
18632   W (ret);
18633   return ret;
18634 }
18635
18636 static int
18637 api_netmap_delete (vat_main_t * vam)
18638 {
18639   unformat_input_t *i = vam->input;
18640   vl_api_netmap_delete_t *mp;
18641   u8 *if_name = 0;
18642   int ret;
18643
18644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18645     {
18646       if (unformat (i, "name %s", &if_name))
18647         vec_add1 (if_name, 0);
18648       else
18649         break;
18650     }
18651
18652   if (!vec_len (if_name))
18653     {
18654       errmsg ("interface name must be specified");
18655       return -99;
18656     }
18657
18658   if (vec_len (if_name) > 64)
18659     {
18660       errmsg ("interface name too long");
18661       return -99;
18662     }
18663
18664   M (NETMAP_DELETE, mp);
18665
18666   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18667   vec_free (if_name);
18668
18669   S (mp);
18670   W (ret);
18671   return ret;
18672 }
18673
18674 static u8 *
18675 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18676 {
18677   vl_api_fib_path_nh_proto_t proto =
18678     va_arg (*args, vl_api_fib_path_nh_proto_t);
18679
18680   switch (proto)
18681     {
18682     case FIB_API_PATH_NH_PROTO_IP4:
18683       s = format (s, "ip4");
18684       break;
18685     case FIB_API_PATH_NH_PROTO_IP6:
18686       s = format (s, "ip6");
18687       break;
18688     case FIB_API_PATH_NH_PROTO_MPLS:
18689       s = format (s, "mpls");
18690       break;
18691     case FIB_API_PATH_NH_PROTO_BIER:
18692       s = format (s, "bier");
18693       break;
18694     case FIB_API_PATH_NH_PROTO_ETHERNET:
18695       s = format (s, "ethernet");
18696       break;
18697     }
18698
18699   return (s);
18700 }
18701
18702 static u8 *
18703 format_vl_api_ip_address_union (u8 * s, va_list * args)
18704 {
18705   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18706   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18707
18708   switch (af)
18709     {
18710     case ADDRESS_IP4:
18711       s = format (s, "%U", format_ip4_address, u->ip4);
18712       break;
18713     case ADDRESS_IP6:
18714       s = format (s, "%U", format_ip6_address, u->ip6);
18715       break;
18716     }
18717   return (s);
18718 }
18719
18720 static u8 *
18721 format_vl_api_fib_path_type (u8 * s, va_list * args)
18722 {
18723   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18724
18725   switch (t)
18726     {
18727     case FIB_API_PATH_TYPE_NORMAL:
18728       s = format (s, "normal");
18729       break;
18730     case FIB_API_PATH_TYPE_LOCAL:
18731       s = format (s, "local");
18732       break;
18733     case FIB_API_PATH_TYPE_DROP:
18734       s = format (s, "drop");
18735       break;
18736     case FIB_API_PATH_TYPE_UDP_ENCAP:
18737       s = format (s, "udp-encap");
18738       break;
18739     case FIB_API_PATH_TYPE_BIER_IMP:
18740       s = format (s, "bier-imp");
18741       break;
18742     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18743       s = format (s, "unreach");
18744       break;
18745     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18746       s = format (s, "prohibit");
18747       break;
18748     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18749       s = format (s, "src-lookup");
18750       break;
18751     case FIB_API_PATH_TYPE_DVR:
18752       s = format (s, "dvr");
18753       break;
18754     case FIB_API_PATH_TYPE_INTERFACE_RX:
18755       s = format (s, "interface-rx");
18756       break;
18757     case FIB_API_PATH_TYPE_CLASSIFY:
18758       s = format (s, "classify");
18759       break;
18760     }
18761
18762   return (s);
18763 }
18764
18765 static void
18766 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18767 {
18768   print (vam->ofp,
18769          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18770          ntohl (fp->weight), ntohl (fp->sw_if_index),
18771          format_vl_api_fib_path_type, fp->type,
18772          format_fib_api_path_nh_proto, fp->proto,
18773          format_vl_api_ip_address_union, &fp->nh.address);
18774 }
18775
18776 static void
18777 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18778                                  vl_api_fib_path_t * fp)
18779 {
18780   struct in_addr ip4;
18781   struct in6_addr ip6;
18782
18783   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18784   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18785   vat_json_object_add_uint (node, "type", fp->type);
18786   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18787   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18788     {
18789       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18790       vat_json_object_add_ip4 (node, "next_hop", ip4);
18791     }
18792   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18793     {
18794       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18795       vat_json_object_add_ip6 (node, "next_hop", ip6);
18796     }
18797 }
18798
18799 static void
18800 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18801 {
18802   vat_main_t *vam = &vat_main;
18803   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18804   vl_api_fib_path_t *fp;
18805   i32 i;
18806
18807   print (vam->ofp, "sw_if_index %d via:",
18808          ntohl (mp->mt_tunnel.mt_sw_if_index));
18809   fp = mp->mt_tunnel.mt_paths;
18810   for (i = 0; i < count; i++)
18811     {
18812       vl_api_fib_path_print (vam, fp);
18813       fp++;
18814     }
18815
18816   print (vam->ofp, "");
18817 }
18818
18819 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18820 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18821
18822 static void
18823 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18824 {
18825   vat_main_t *vam = &vat_main;
18826   vat_json_node_t *node = NULL;
18827   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18828   vl_api_fib_path_t *fp;
18829   i32 i;
18830
18831   if (VAT_JSON_ARRAY != vam->json_tree.type)
18832     {
18833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18834       vat_json_init_array (&vam->json_tree);
18835     }
18836   node = vat_json_array_add (&vam->json_tree);
18837
18838   vat_json_init_object (node);
18839   vat_json_object_add_uint (node, "sw_if_index",
18840                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18841
18842   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18843
18844   fp = mp->mt_tunnel.mt_paths;
18845   for (i = 0; i < count; i++)
18846     {
18847       vl_api_mpls_fib_path_json_print (node, fp);
18848       fp++;
18849     }
18850 }
18851
18852 static int
18853 api_mpls_tunnel_dump (vat_main_t * vam)
18854 {
18855   vl_api_mpls_tunnel_dump_t *mp;
18856   vl_api_control_ping_t *mp_ping;
18857   int ret;
18858
18859   M (MPLS_TUNNEL_DUMP, mp);
18860
18861   S (mp);
18862
18863   /* Use a control ping for synchronization */
18864   MPING (CONTROL_PING, mp_ping);
18865   S (mp_ping);
18866
18867   W (ret);
18868   return ret;
18869 }
18870
18871 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18872 #define vl_api_mpls_table_details_t_print vl_noop_handler
18873
18874
18875 static void
18876 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18877 {
18878   vat_main_t *vam = &vat_main;
18879
18880   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18881 }
18882
18883 static void vl_api_mpls_table_details_t_handler_json
18884   (vl_api_mpls_table_details_t * mp)
18885 {
18886   vat_main_t *vam = &vat_main;
18887   vat_json_node_t *node = NULL;
18888
18889   if (VAT_JSON_ARRAY != vam->json_tree.type)
18890     {
18891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18892       vat_json_init_array (&vam->json_tree);
18893     }
18894   node = vat_json_array_add (&vam->json_tree);
18895
18896   vat_json_init_object (node);
18897   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18898 }
18899
18900 static int
18901 api_mpls_table_dump (vat_main_t * vam)
18902 {
18903   vl_api_mpls_table_dump_t *mp;
18904   vl_api_control_ping_t *mp_ping;
18905   int ret;
18906
18907   M (MPLS_TABLE_DUMP, mp);
18908   S (mp);
18909
18910   /* Use a control ping for synchronization */
18911   MPING (CONTROL_PING, mp_ping);
18912   S (mp_ping);
18913
18914   W (ret);
18915   return ret;
18916 }
18917
18918 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18919 #define vl_api_mpls_route_details_t_print vl_noop_handler
18920
18921 static void
18922 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18923 {
18924   vat_main_t *vam = &vat_main;
18925   int count = ntohl (mp->mr_route.mr_n_paths);
18926   vl_api_fib_path_t *fp;
18927   int i;
18928
18929   print (vam->ofp,
18930          "table-id %d, label %u, ess_bit %u",
18931          ntohl (mp->mr_route.mr_table_id),
18932          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18933   fp = mp->mr_route.mr_paths;
18934   for (i = 0; i < count; i++)
18935     {
18936       vl_api_fib_path_print (vam, fp);
18937       fp++;
18938     }
18939 }
18940
18941 static void vl_api_mpls_route_details_t_handler_json
18942   (vl_api_mpls_route_details_t * mp)
18943 {
18944   vat_main_t *vam = &vat_main;
18945   int count = ntohl (mp->mr_route.mr_n_paths);
18946   vat_json_node_t *node = NULL;
18947   vl_api_fib_path_t *fp;
18948   int i;
18949
18950   if (VAT_JSON_ARRAY != vam->json_tree.type)
18951     {
18952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18953       vat_json_init_array (&vam->json_tree);
18954     }
18955   node = vat_json_array_add (&vam->json_tree);
18956
18957   vat_json_init_object (node);
18958   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18959   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18960   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18961   vat_json_object_add_uint (node, "path_count", count);
18962   fp = mp->mr_route.mr_paths;
18963   for (i = 0; i < count; i++)
18964     {
18965       vl_api_mpls_fib_path_json_print (node, fp);
18966       fp++;
18967     }
18968 }
18969
18970 static int
18971 api_mpls_route_dump (vat_main_t * vam)
18972 {
18973   unformat_input_t *input = vam->input;
18974   vl_api_mpls_route_dump_t *mp;
18975   vl_api_control_ping_t *mp_ping;
18976   u32 table_id;
18977   int ret;
18978
18979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18980     {
18981       if (unformat (input, "table_id %d", &table_id))
18982         ;
18983       else
18984         break;
18985     }
18986   if (table_id == ~0)
18987     {
18988       errmsg ("missing table id");
18989       return -99;
18990     }
18991
18992   M (MPLS_ROUTE_DUMP, mp);
18993
18994   mp->table.mt_table_id = ntohl (table_id);
18995   S (mp);
18996
18997   /* Use a control ping for synchronization */
18998   MPING (CONTROL_PING, mp_ping);
18999   S (mp_ping);
19000
19001   W (ret);
19002   return ret;
19003 }
19004
19005 #define vl_api_ip_table_details_t_endian vl_noop_handler
19006 #define vl_api_ip_table_details_t_print vl_noop_handler
19007
19008 static void
19009 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19010 {
19011   vat_main_t *vam = &vat_main;
19012
19013   print (vam->ofp,
19014          "%s; table-id %d, prefix %U/%d",
19015          mp->table.name, ntohl (mp->table.table_id));
19016 }
19017
19018
19019 static void vl_api_ip_table_details_t_handler_json
19020   (vl_api_ip_table_details_t * mp)
19021 {
19022   vat_main_t *vam = &vat_main;
19023   vat_json_node_t *node = NULL;
19024
19025   if (VAT_JSON_ARRAY != vam->json_tree.type)
19026     {
19027       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19028       vat_json_init_array (&vam->json_tree);
19029     }
19030   node = vat_json_array_add (&vam->json_tree);
19031
19032   vat_json_init_object (node);
19033   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19034 }
19035
19036 static int
19037 api_ip_table_dump (vat_main_t * vam)
19038 {
19039   vl_api_ip_table_dump_t *mp;
19040   vl_api_control_ping_t *mp_ping;
19041   int ret;
19042
19043   M (IP_TABLE_DUMP, mp);
19044   S (mp);
19045
19046   /* Use a control ping for synchronization */
19047   MPING (CONTROL_PING, mp_ping);
19048   S (mp_ping);
19049
19050   W (ret);
19051   return ret;
19052 }
19053
19054 static int
19055 api_ip_mtable_dump (vat_main_t * vam)
19056 {
19057   vl_api_ip_mtable_dump_t *mp;
19058   vl_api_control_ping_t *mp_ping;
19059   int ret;
19060
19061   M (IP_MTABLE_DUMP, mp);
19062   S (mp);
19063
19064   /* Use a control ping for synchronization */
19065   MPING (CONTROL_PING, mp_ping);
19066   S (mp_ping);
19067
19068   W (ret);
19069   return ret;
19070 }
19071
19072 static int
19073 api_ip_mroute_dump (vat_main_t * vam)
19074 {
19075   unformat_input_t *input = vam->input;
19076   vl_api_control_ping_t *mp_ping;
19077   vl_api_ip_mroute_dump_t *mp;
19078   int ret, is_ip6;
19079   u32 table_id;
19080
19081   is_ip6 = 0;
19082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19083     {
19084       if (unformat (input, "table_id %d", &table_id))
19085         ;
19086       else if (unformat (input, "ip6"))
19087         is_ip6 = 1;
19088       else if (unformat (input, "ip4"))
19089         is_ip6 = 0;
19090       else
19091         break;
19092     }
19093   if (table_id == ~0)
19094     {
19095       errmsg ("missing table id");
19096       return -99;
19097     }
19098
19099   M (IP_MROUTE_DUMP, mp);
19100   mp->table.table_id = table_id;
19101   mp->table.is_ip6 = is_ip6;
19102   S (mp);
19103
19104   /* Use a control ping for synchronization */
19105   MPING (CONTROL_PING, mp_ping);
19106   S (mp_ping);
19107
19108   W (ret);
19109   return ret;
19110 }
19111
19112 static void vl_api_ip_neighbor_details_t_handler
19113   (vl_api_ip_neighbor_details_t * mp)
19114 {
19115   vat_main_t *vam = &vat_main;
19116
19117   print (vam->ofp, "%c %U %U",
19118          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19119          format_vl_api_mac_address, &mp->neighbor.mac_address,
19120          format_vl_api_address, &mp->neighbor.ip_address);
19121 }
19122
19123 static void vl_api_ip_neighbor_details_t_handler_json
19124   (vl_api_ip_neighbor_details_t * mp)
19125 {
19126
19127   vat_main_t *vam = &vat_main;
19128   vat_json_node_t *node;
19129
19130   if (VAT_JSON_ARRAY != vam->json_tree.type)
19131     {
19132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19133       vat_json_init_array (&vam->json_tree);
19134     }
19135   node = vat_json_array_add (&vam->json_tree);
19136
19137   vat_json_init_object (node);
19138   vat_json_object_add_string_copy
19139     (node, "flag",
19140      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19141       (u8 *) "static" : (u8 *) "dynamic"));
19142
19143   vat_json_object_add_string_copy (node, "link_layer",
19144                                    format (0, "%U", format_vl_api_mac_address,
19145                                            &mp->neighbor.mac_address));
19146   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19147 }
19148
19149 static int
19150 api_ip_neighbor_dump (vat_main_t * vam)
19151 {
19152   unformat_input_t *i = vam->input;
19153   vl_api_ip_neighbor_dump_t *mp;
19154   vl_api_control_ping_t *mp_ping;
19155   u8 is_ipv6 = 0;
19156   u32 sw_if_index = ~0;
19157   int ret;
19158
19159   /* Parse args required to build the message */
19160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19161     {
19162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19163         ;
19164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19165         ;
19166       else if (unformat (i, "ip6"))
19167         is_ipv6 = 1;
19168       else
19169         break;
19170     }
19171
19172   if (sw_if_index == ~0)
19173     {
19174       errmsg ("missing interface name or sw_if_index");
19175       return -99;
19176     }
19177
19178   M (IP_NEIGHBOR_DUMP, mp);
19179   mp->is_ipv6 = (u8) is_ipv6;
19180   mp->sw_if_index = ntohl (sw_if_index);
19181   S (mp);
19182
19183   /* Use a control ping for synchronization */
19184   MPING (CONTROL_PING, mp_ping);
19185   S (mp_ping);
19186
19187   W (ret);
19188   return ret;
19189 }
19190
19191 #define vl_api_ip_route_details_t_endian vl_noop_handler
19192 #define vl_api_ip_route_details_t_print vl_noop_handler
19193
19194 static void
19195 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19196 {
19197   vat_main_t *vam = &vat_main;
19198   u8 count = mp->route.n_paths;
19199   vl_api_fib_path_t *fp;
19200   int i;
19201
19202   print (vam->ofp,
19203          "table-id %d, prefix %U/%d",
19204          ntohl (mp->route.table_id),
19205          format_ip46_address,
19206          mp->route.prefix.address, mp->route.prefix.address_length);
19207   for (i = 0; i < count; i++)
19208     {
19209       fp = &mp->route.paths[i];
19210
19211       vl_api_fib_path_print (vam, fp);
19212       fp++;
19213     }
19214 }
19215
19216 static void vl_api_ip_route_details_t_handler_json
19217   (vl_api_ip_route_details_t * mp)
19218 {
19219   vat_main_t *vam = &vat_main;
19220   u8 count = mp->route.n_paths;
19221   vat_json_node_t *node = NULL;
19222   struct in_addr ip4;
19223   struct in6_addr ip6;
19224   vl_api_fib_path_t *fp;
19225   int i;
19226
19227   if (VAT_JSON_ARRAY != vam->json_tree.type)
19228     {
19229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19230       vat_json_init_array (&vam->json_tree);
19231     }
19232   node = vat_json_array_add (&vam->json_tree);
19233
19234   vat_json_init_object (node);
19235   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19236   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19237     {
19238       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19239       vat_json_object_add_ip6 (node, "prefix", ip6);
19240     }
19241   else
19242     {
19243       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19244       vat_json_object_add_ip4 (node, "prefix", ip4);
19245     }
19246   vat_json_object_add_uint (node, "mask_length",
19247                             mp->route.prefix.address_length);
19248   vat_json_object_add_uint (node, "path_count", count);
19249   for (i = 0; i < count; i++)
19250     {
19251       fp = &mp->route.paths[i];
19252       vl_api_mpls_fib_path_json_print (node, fp);
19253     }
19254 }
19255
19256 static int
19257 api_ip_route_dump (vat_main_t * vam)
19258 {
19259   unformat_input_t *input = vam->input;
19260   vl_api_ip_route_dump_t *mp;
19261   vl_api_control_ping_t *mp_ping;
19262   u32 table_id;
19263   u8 is_ip6;
19264   int ret;
19265
19266   is_ip6 = 0;
19267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19268     {
19269       if (unformat (input, "table_id %d", &table_id))
19270         ;
19271       else if (unformat (input, "ip6"))
19272         is_ip6 = 1;
19273       else if (unformat (input, "ip4"))
19274         is_ip6 = 0;
19275       else
19276         break;
19277     }
19278   if (table_id == ~0)
19279     {
19280       errmsg ("missing table id");
19281       return -99;
19282     }
19283
19284   M (IP_ROUTE_DUMP, mp);
19285
19286   mp->table.table_id = table_id;
19287   mp->table.is_ip6 = is_ip6;
19288
19289   S (mp);
19290
19291   /* Use a control ping for synchronization */
19292   MPING (CONTROL_PING, mp_ping);
19293   S (mp_ping);
19294
19295   W (ret);
19296   return ret;
19297 }
19298
19299 int
19300 api_classify_table_ids (vat_main_t * vam)
19301 {
19302   vl_api_classify_table_ids_t *mp;
19303   int ret;
19304
19305   /* Construct the API message */
19306   M (CLASSIFY_TABLE_IDS, mp);
19307   mp->context = 0;
19308
19309   S (mp);
19310   W (ret);
19311   return ret;
19312 }
19313
19314 int
19315 api_classify_table_by_interface (vat_main_t * vam)
19316 {
19317   unformat_input_t *input = vam->input;
19318   vl_api_classify_table_by_interface_t *mp;
19319
19320   u32 sw_if_index = ~0;
19321   int ret;
19322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19323     {
19324       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19325         ;
19326       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19327         ;
19328       else
19329         break;
19330     }
19331   if (sw_if_index == ~0)
19332     {
19333       errmsg ("missing interface name or sw_if_index");
19334       return -99;
19335     }
19336
19337   /* Construct the API message */
19338   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19339   mp->context = 0;
19340   mp->sw_if_index = ntohl (sw_if_index);
19341
19342   S (mp);
19343   W (ret);
19344   return ret;
19345 }
19346
19347 int
19348 api_classify_table_info (vat_main_t * vam)
19349 {
19350   unformat_input_t *input = vam->input;
19351   vl_api_classify_table_info_t *mp;
19352
19353   u32 table_id = ~0;
19354   int ret;
19355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19356     {
19357       if (unformat (input, "table_id %d", &table_id))
19358         ;
19359       else
19360         break;
19361     }
19362   if (table_id == ~0)
19363     {
19364       errmsg ("missing table id");
19365       return -99;
19366     }
19367
19368   /* Construct the API message */
19369   M (CLASSIFY_TABLE_INFO, mp);
19370   mp->context = 0;
19371   mp->table_id = ntohl (table_id);
19372
19373   S (mp);
19374   W (ret);
19375   return ret;
19376 }
19377
19378 int
19379 api_classify_session_dump (vat_main_t * vam)
19380 {
19381   unformat_input_t *input = vam->input;
19382   vl_api_classify_session_dump_t *mp;
19383   vl_api_control_ping_t *mp_ping;
19384
19385   u32 table_id = ~0;
19386   int ret;
19387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19388     {
19389       if (unformat (input, "table_id %d", &table_id))
19390         ;
19391       else
19392         break;
19393     }
19394   if (table_id == ~0)
19395     {
19396       errmsg ("missing table id");
19397       return -99;
19398     }
19399
19400   /* Construct the API message */
19401   M (CLASSIFY_SESSION_DUMP, mp);
19402   mp->context = 0;
19403   mp->table_id = ntohl (table_id);
19404   S (mp);
19405
19406   /* Use a control ping for synchronization */
19407   MPING (CONTROL_PING, mp_ping);
19408   S (mp_ping);
19409
19410   W (ret);
19411   return ret;
19412 }
19413
19414 static void
19415 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19416 {
19417   vat_main_t *vam = &vat_main;
19418
19419   print (vam->ofp, "collector_address %U, collector_port %d, "
19420          "src_address %U, vrf_id %d, path_mtu %u, "
19421          "template_interval %u, udp_checksum %d",
19422          format_ip4_address, mp->collector_address,
19423          ntohs (mp->collector_port),
19424          format_ip4_address, mp->src_address,
19425          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19426          ntohl (mp->template_interval), mp->udp_checksum);
19427
19428   vam->retval = 0;
19429   vam->result_ready = 1;
19430 }
19431
19432 static void
19433   vl_api_ipfix_exporter_details_t_handler_json
19434   (vl_api_ipfix_exporter_details_t * mp)
19435 {
19436   vat_main_t *vam = &vat_main;
19437   vat_json_node_t node;
19438   struct in_addr collector_address;
19439   struct in_addr src_address;
19440
19441   vat_json_init_object (&node);
19442   clib_memcpy (&collector_address, &mp->collector_address,
19443                sizeof (collector_address));
19444   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19445   vat_json_object_add_uint (&node, "collector_port",
19446                             ntohs (mp->collector_port));
19447   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19448   vat_json_object_add_ip4 (&node, "src_address", src_address);
19449   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19450   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19451   vat_json_object_add_uint (&node, "template_interval",
19452                             ntohl (mp->template_interval));
19453   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19454
19455   vat_json_print (vam->ofp, &node);
19456   vat_json_free (&node);
19457   vam->retval = 0;
19458   vam->result_ready = 1;
19459 }
19460
19461 int
19462 api_ipfix_exporter_dump (vat_main_t * vam)
19463 {
19464   vl_api_ipfix_exporter_dump_t *mp;
19465   int ret;
19466
19467   /* Construct the API message */
19468   M (IPFIX_EXPORTER_DUMP, mp);
19469   mp->context = 0;
19470
19471   S (mp);
19472   W (ret);
19473   return ret;
19474 }
19475
19476 static int
19477 api_ipfix_classify_stream_dump (vat_main_t * vam)
19478 {
19479   vl_api_ipfix_classify_stream_dump_t *mp;
19480   int ret;
19481
19482   /* Construct the API message */
19483   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19484   mp->context = 0;
19485
19486   S (mp);
19487   W (ret);
19488   return ret;
19489   /* NOTREACHED */
19490   return 0;
19491 }
19492
19493 static void
19494   vl_api_ipfix_classify_stream_details_t_handler
19495   (vl_api_ipfix_classify_stream_details_t * mp)
19496 {
19497   vat_main_t *vam = &vat_main;
19498   print (vam->ofp, "domain_id %d, src_port %d",
19499          ntohl (mp->domain_id), ntohs (mp->src_port));
19500   vam->retval = 0;
19501   vam->result_ready = 1;
19502 }
19503
19504 static void
19505   vl_api_ipfix_classify_stream_details_t_handler_json
19506   (vl_api_ipfix_classify_stream_details_t * mp)
19507 {
19508   vat_main_t *vam = &vat_main;
19509   vat_json_node_t node;
19510
19511   vat_json_init_object (&node);
19512   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19513   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19514
19515   vat_json_print (vam->ofp, &node);
19516   vat_json_free (&node);
19517   vam->retval = 0;
19518   vam->result_ready = 1;
19519 }
19520
19521 static int
19522 api_ipfix_classify_table_dump (vat_main_t * vam)
19523 {
19524   vl_api_ipfix_classify_table_dump_t *mp;
19525   vl_api_control_ping_t *mp_ping;
19526   int ret;
19527
19528   if (!vam->json_output)
19529     {
19530       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19531              "transport_protocol");
19532     }
19533
19534   /* Construct the API message */
19535   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19536
19537   /* send it... */
19538   S (mp);
19539
19540   /* Use a control ping for synchronization */
19541   MPING (CONTROL_PING, mp_ping);
19542   S (mp_ping);
19543
19544   W (ret);
19545   return ret;
19546 }
19547
19548 static void
19549   vl_api_ipfix_classify_table_details_t_handler
19550   (vl_api_ipfix_classify_table_details_t * mp)
19551 {
19552   vat_main_t *vam = &vat_main;
19553   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19554          mp->transport_protocol);
19555 }
19556
19557 static void
19558   vl_api_ipfix_classify_table_details_t_handler_json
19559   (vl_api_ipfix_classify_table_details_t * mp)
19560 {
19561   vat_json_node_t *node = NULL;
19562   vat_main_t *vam = &vat_main;
19563
19564   if (VAT_JSON_ARRAY != vam->json_tree.type)
19565     {
19566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19567       vat_json_init_array (&vam->json_tree);
19568     }
19569
19570   node = vat_json_array_add (&vam->json_tree);
19571   vat_json_init_object (node);
19572
19573   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19574   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19575   vat_json_object_add_uint (node, "transport_protocol",
19576                             mp->transport_protocol);
19577 }
19578
19579 static int
19580 api_sw_interface_span_enable_disable (vat_main_t * vam)
19581 {
19582   unformat_input_t *i = vam->input;
19583   vl_api_sw_interface_span_enable_disable_t *mp;
19584   u32 src_sw_if_index = ~0;
19585   u32 dst_sw_if_index = ~0;
19586   u8 state = 3;
19587   int ret;
19588   u8 is_l2 = 0;
19589
19590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19591     {
19592       if (unformat
19593           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19594         ;
19595       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19596         ;
19597       else
19598         if (unformat
19599             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19600         ;
19601       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19602         ;
19603       else if (unformat (i, "disable"))
19604         state = 0;
19605       else if (unformat (i, "rx"))
19606         state = 1;
19607       else if (unformat (i, "tx"))
19608         state = 2;
19609       else if (unformat (i, "both"))
19610         state = 3;
19611       else if (unformat (i, "l2"))
19612         is_l2 = 1;
19613       else
19614         break;
19615     }
19616
19617   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19618
19619   mp->sw_if_index_from = htonl (src_sw_if_index);
19620   mp->sw_if_index_to = htonl (dst_sw_if_index);
19621   mp->state = state;
19622   mp->is_l2 = is_l2;
19623
19624   S (mp);
19625   W (ret);
19626   return ret;
19627 }
19628
19629 static void
19630 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19631                                             * mp)
19632 {
19633   vat_main_t *vam = &vat_main;
19634   u8 *sw_if_from_name = 0;
19635   u8 *sw_if_to_name = 0;
19636   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19637   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19638   char *states[] = { "none", "rx", "tx", "both" };
19639   hash_pair_t *p;
19640
19641   /* *INDENT-OFF* */
19642   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19643   ({
19644     if ((u32) p->value[0] == sw_if_index_from)
19645       {
19646         sw_if_from_name = (u8 *)(p->key);
19647         if (sw_if_to_name)
19648           break;
19649       }
19650     if ((u32) p->value[0] == sw_if_index_to)
19651       {
19652         sw_if_to_name = (u8 *)(p->key);
19653         if (sw_if_from_name)
19654           break;
19655       }
19656   }));
19657   /* *INDENT-ON* */
19658   print (vam->ofp, "%20s => %20s (%s) %s",
19659          sw_if_from_name, sw_if_to_name, states[mp->state],
19660          mp->is_l2 ? "l2" : "device");
19661 }
19662
19663 static void
19664   vl_api_sw_interface_span_details_t_handler_json
19665   (vl_api_sw_interface_span_details_t * mp)
19666 {
19667   vat_main_t *vam = &vat_main;
19668   vat_json_node_t *node = NULL;
19669   u8 *sw_if_from_name = 0;
19670   u8 *sw_if_to_name = 0;
19671   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19672   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19673   hash_pair_t *p;
19674
19675   /* *INDENT-OFF* */
19676   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19677   ({
19678     if ((u32) p->value[0] == sw_if_index_from)
19679       {
19680         sw_if_from_name = (u8 *)(p->key);
19681         if (sw_if_to_name)
19682           break;
19683       }
19684     if ((u32) p->value[0] == sw_if_index_to)
19685       {
19686         sw_if_to_name = (u8 *)(p->key);
19687         if (sw_if_from_name)
19688           break;
19689       }
19690   }));
19691   /* *INDENT-ON* */
19692
19693   if (VAT_JSON_ARRAY != vam->json_tree.type)
19694     {
19695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19696       vat_json_init_array (&vam->json_tree);
19697     }
19698   node = vat_json_array_add (&vam->json_tree);
19699
19700   vat_json_init_object (node);
19701   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19702   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19703   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19704   if (0 != sw_if_to_name)
19705     {
19706       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19707     }
19708   vat_json_object_add_uint (node, "state", mp->state);
19709   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19710 }
19711
19712 static int
19713 api_sw_interface_span_dump (vat_main_t * vam)
19714 {
19715   unformat_input_t *input = vam->input;
19716   vl_api_sw_interface_span_dump_t *mp;
19717   vl_api_control_ping_t *mp_ping;
19718   u8 is_l2 = 0;
19719   int ret;
19720
19721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19722     {
19723       if (unformat (input, "l2"))
19724         is_l2 = 1;
19725       else
19726         break;
19727     }
19728
19729   M (SW_INTERFACE_SPAN_DUMP, mp);
19730   mp->is_l2 = is_l2;
19731   S (mp);
19732
19733   /* Use a control ping for synchronization */
19734   MPING (CONTROL_PING, mp_ping);
19735   S (mp_ping);
19736
19737   W (ret);
19738   return ret;
19739 }
19740
19741 int
19742 api_pg_create_interface (vat_main_t * vam)
19743 {
19744   unformat_input_t *input = vam->input;
19745   vl_api_pg_create_interface_t *mp;
19746
19747   u32 if_id = ~0;
19748   int ret;
19749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19750     {
19751       if (unformat (input, "if_id %d", &if_id))
19752         ;
19753       else
19754         break;
19755     }
19756   if (if_id == ~0)
19757     {
19758       errmsg ("missing pg interface index");
19759       return -99;
19760     }
19761
19762   /* Construct the API message */
19763   M (PG_CREATE_INTERFACE, mp);
19764   mp->context = 0;
19765   mp->interface_id = ntohl (if_id);
19766
19767   S (mp);
19768   W (ret);
19769   return ret;
19770 }
19771
19772 int
19773 api_pg_capture (vat_main_t * vam)
19774 {
19775   unformat_input_t *input = vam->input;
19776   vl_api_pg_capture_t *mp;
19777
19778   u32 if_id = ~0;
19779   u8 enable = 1;
19780   u32 count = 1;
19781   u8 pcap_file_set = 0;
19782   u8 *pcap_file = 0;
19783   int ret;
19784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19785     {
19786       if (unformat (input, "if_id %d", &if_id))
19787         ;
19788       else if (unformat (input, "pcap %s", &pcap_file))
19789         pcap_file_set = 1;
19790       else if (unformat (input, "count %d", &count))
19791         ;
19792       else if (unformat (input, "disable"))
19793         enable = 0;
19794       else
19795         break;
19796     }
19797   if (if_id == ~0)
19798     {
19799       errmsg ("missing pg interface index");
19800       return -99;
19801     }
19802   if (pcap_file_set > 0)
19803     {
19804       if (vec_len (pcap_file) > 255)
19805         {
19806           errmsg ("pcap file name is too long");
19807           return -99;
19808         }
19809     }
19810
19811   u32 name_len = vec_len (pcap_file);
19812   /* Construct the API message */
19813   M (PG_CAPTURE, mp);
19814   mp->context = 0;
19815   mp->interface_id = ntohl (if_id);
19816   mp->is_enabled = enable;
19817   mp->count = ntohl (count);
19818   mp->pcap_name_length = ntohl (name_len);
19819   if (pcap_file_set != 0)
19820     {
19821       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19822     }
19823   vec_free (pcap_file);
19824
19825   S (mp);
19826   W (ret);
19827   return ret;
19828 }
19829
19830 int
19831 api_pg_enable_disable (vat_main_t * vam)
19832 {
19833   unformat_input_t *input = vam->input;
19834   vl_api_pg_enable_disable_t *mp;
19835
19836   u8 enable = 1;
19837   u8 stream_name_set = 0;
19838   u8 *stream_name = 0;
19839   int ret;
19840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19841     {
19842       if (unformat (input, "stream %s", &stream_name))
19843         stream_name_set = 1;
19844       else if (unformat (input, "disable"))
19845         enable = 0;
19846       else
19847         break;
19848     }
19849
19850   if (stream_name_set > 0)
19851     {
19852       if (vec_len (stream_name) > 255)
19853         {
19854           errmsg ("stream name too long");
19855           return -99;
19856         }
19857     }
19858
19859   u32 name_len = vec_len (stream_name);
19860   /* Construct the API message */
19861   M (PG_ENABLE_DISABLE, mp);
19862   mp->context = 0;
19863   mp->is_enabled = enable;
19864   if (stream_name_set != 0)
19865     {
19866       mp->stream_name_length = ntohl (name_len);
19867       clib_memcpy (mp->stream_name, stream_name, name_len);
19868     }
19869   vec_free (stream_name);
19870
19871   S (mp);
19872   W (ret);
19873   return ret;
19874 }
19875
19876 int
19877 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19878 {
19879   unformat_input_t *input = vam->input;
19880   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19881
19882   u16 *low_ports = 0;
19883   u16 *high_ports = 0;
19884   u16 this_low;
19885   u16 this_hi;
19886   vl_api_prefix_t prefix;
19887   u32 tmp, tmp2;
19888   u8 prefix_set = 0;
19889   u32 vrf_id = ~0;
19890   u8 is_add = 1;
19891   int ret;
19892
19893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19894     {
19895       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19896         prefix_set = 1;
19897       else if (unformat (input, "vrf %d", &vrf_id))
19898         ;
19899       else if (unformat (input, "del"))
19900         is_add = 0;
19901       else if (unformat (input, "port %d", &tmp))
19902         {
19903           if (tmp == 0 || tmp > 65535)
19904             {
19905               errmsg ("port %d out of range", tmp);
19906               return -99;
19907             }
19908           this_low = tmp;
19909           this_hi = this_low + 1;
19910           vec_add1 (low_ports, this_low);
19911           vec_add1 (high_ports, this_hi);
19912         }
19913       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19914         {
19915           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19916             {
19917               errmsg ("incorrect range parameters");
19918               return -99;
19919             }
19920           this_low = tmp;
19921           /* Note: in debug CLI +1 is added to high before
19922              passing to real fn that does "the work"
19923              (ip_source_and_port_range_check_add_del).
19924              This fn is a wrapper around the binary API fn a
19925              control plane will call, which expects this increment
19926              to have occurred. Hence letting the binary API control
19927              plane fn do the increment for consistency between VAT
19928              and other control planes.
19929            */
19930           this_hi = tmp2;
19931           vec_add1 (low_ports, this_low);
19932           vec_add1 (high_ports, this_hi);
19933         }
19934       else
19935         break;
19936     }
19937
19938   if (prefix_set == 0)
19939     {
19940       errmsg ("<address>/<mask> not specified");
19941       return -99;
19942     }
19943
19944   if (vrf_id == ~0)
19945     {
19946       errmsg ("VRF ID required, not specified");
19947       return -99;
19948     }
19949
19950   if (vrf_id == 0)
19951     {
19952       errmsg
19953         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19954       return -99;
19955     }
19956
19957   if (vec_len (low_ports) == 0)
19958     {
19959       errmsg ("At least one port or port range required");
19960       return -99;
19961     }
19962
19963   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19964
19965   mp->is_add = is_add;
19966
19967   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19968
19969   mp->number_of_ranges = vec_len (low_ports);
19970
19971   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19972   vec_free (low_ports);
19973
19974   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19975   vec_free (high_ports);
19976
19977   mp->vrf_id = ntohl (vrf_id);
19978
19979   S (mp);
19980   W (ret);
19981   return ret;
19982 }
19983
19984 int
19985 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19986 {
19987   unformat_input_t *input = vam->input;
19988   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19989   u32 sw_if_index = ~0;
19990   int vrf_set = 0;
19991   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19992   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19993   u8 is_add = 1;
19994   int ret;
19995
19996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19997     {
19998       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19999         ;
20000       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20001         ;
20002       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20003         vrf_set = 1;
20004       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20005         vrf_set = 1;
20006       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20007         vrf_set = 1;
20008       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20009         vrf_set = 1;
20010       else if (unformat (input, "del"))
20011         is_add = 0;
20012       else
20013         break;
20014     }
20015
20016   if (sw_if_index == ~0)
20017     {
20018       errmsg ("Interface required but not specified");
20019       return -99;
20020     }
20021
20022   if (vrf_set == 0)
20023     {
20024       errmsg ("VRF ID required but not specified");
20025       return -99;
20026     }
20027
20028   if (tcp_out_vrf_id == 0
20029       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20030     {
20031       errmsg
20032         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20033       return -99;
20034     }
20035
20036   /* Construct the API message */
20037   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20038
20039   mp->sw_if_index = ntohl (sw_if_index);
20040   mp->is_add = is_add;
20041   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20042   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20043   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20044   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20045
20046   /* send it... */
20047   S (mp);
20048
20049   /* Wait for a reply... */
20050   W (ret);
20051   return ret;
20052 }
20053
20054 static int
20055 api_set_punt (vat_main_t * vam)
20056 {
20057   unformat_input_t *i = vam->input;
20058   vl_api_address_family_t af;
20059   vl_api_set_punt_t *mp;
20060   u32 protocol = ~0;
20061   u32 port = ~0;
20062   int is_add = 1;
20063   int ret;
20064
20065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20066     {
20067       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20068         ;
20069       else if (unformat (i, "protocol %d", &protocol))
20070         ;
20071       else if (unformat (i, "port %d", &port))
20072         ;
20073       else if (unformat (i, "del"))
20074         is_add = 0;
20075       else
20076         {
20077           clib_warning ("parse error '%U'", format_unformat_error, i);
20078           return -99;
20079         }
20080     }
20081
20082   M (SET_PUNT, mp);
20083
20084   mp->is_add = (u8) is_add;
20085   mp->punt.type = PUNT_API_TYPE_L4;
20086   mp->punt.punt.l4.af = af;
20087   mp->punt.punt.l4.protocol = (u8) protocol;
20088   mp->punt.punt.l4.port = htons ((u16) port);
20089
20090   S (mp);
20091   W (ret);
20092   return ret;
20093 }
20094
20095 static int
20096 api_delete_subif (vat_main_t * vam)
20097 {
20098   unformat_input_t *i = vam->input;
20099   vl_api_delete_subif_t *mp;
20100   u32 sw_if_index = ~0;
20101   int ret;
20102
20103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20104     {
20105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20106         ;
20107       if (unformat (i, "sw_if_index %d", &sw_if_index))
20108         ;
20109       else
20110         break;
20111     }
20112
20113   if (sw_if_index == ~0)
20114     {
20115       errmsg ("missing sw_if_index");
20116       return -99;
20117     }
20118
20119   /* Construct the API message */
20120   M (DELETE_SUBIF, mp);
20121   mp->sw_if_index = ntohl (sw_if_index);
20122
20123   S (mp);
20124   W (ret);
20125   return ret;
20126 }
20127
20128 #define foreach_pbb_vtr_op      \
20129 _("disable",  L2_VTR_DISABLED)  \
20130 _("pop",  L2_VTR_POP_2)         \
20131 _("push",  L2_VTR_PUSH_2)
20132
20133 static int
20134 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20135 {
20136   unformat_input_t *i = vam->input;
20137   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20138   u32 sw_if_index = ~0, vtr_op = ~0;
20139   u16 outer_tag = ~0;
20140   u8 dmac[6], smac[6];
20141   u8 dmac_set = 0, smac_set = 0;
20142   u16 vlanid = 0;
20143   u32 sid = ~0;
20144   u32 tmp;
20145   int ret;
20146
20147   /* Shut up coverity */
20148   clib_memset (dmac, 0, sizeof (dmac));
20149   clib_memset (smac, 0, sizeof (smac));
20150
20151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20152     {
20153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20154         ;
20155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20156         ;
20157       else if (unformat (i, "vtr_op %d", &vtr_op))
20158         ;
20159 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20160       foreach_pbb_vtr_op
20161 #undef _
20162         else if (unformat (i, "translate_pbb_stag"))
20163         {
20164           if (unformat (i, "%d", &tmp))
20165             {
20166               vtr_op = L2_VTR_TRANSLATE_2_1;
20167               outer_tag = tmp;
20168             }
20169           else
20170             {
20171               errmsg
20172                 ("translate_pbb_stag operation requires outer tag definition");
20173               return -99;
20174             }
20175         }
20176       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20177         dmac_set++;
20178       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20179         smac_set++;
20180       else if (unformat (i, "sid %d", &sid))
20181         ;
20182       else if (unformat (i, "vlanid %d", &tmp))
20183         vlanid = tmp;
20184       else
20185         {
20186           clib_warning ("parse error '%U'", format_unformat_error, i);
20187           return -99;
20188         }
20189     }
20190
20191   if ((sw_if_index == ~0) || (vtr_op == ~0))
20192     {
20193       errmsg ("missing sw_if_index or vtr operation");
20194       return -99;
20195     }
20196   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20197       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20198     {
20199       errmsg
20200         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20201       return -99;
20202     }
20203
20204   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20205   mp->sw_if_index = ntohl (sw_if_index);
20206   mp->vtr_op = ntohl (vtr_op);
20207   mp->outer_tag = ntohs (outer_tag);
20208   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20209   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20210   mp->b_vlanid = ntohs (vlanid);
20211   mp->i_sid = ntohl (sid);
20212
20213   S (mp);
20214   W (ret);
20215   return ret;
20216 }
20217
20218 static int
20219 api_flow_classify_set_interface (vat_main_t * vam)
20220 {
20221   unformat_input_t *i = vam->input;
20222   vl_api_flow_classify_set_interface_t *mp;
20223   u32 sw_if_index;
20224   int sw_if_index_set;
20225   u32 ip4_table_index = ~0;
20226   u32 ip6_table_index = ~0;
20227   u8 is_add = 1;
20228   int ret;
20229
20230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20231     {
20232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20233         sw_if_index_set = 1;
20234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20235         sw_if_index_set = 1;
20236       else if (unformat (i, "del"))
20237         is_add = 0;
20238       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20239         ;
20240       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20241         ;
20242       else
20243         {
20244           clib_warning ("parse error '%U'", format_unformat_error, i);
20245           return -99;
20246         }
20247     }
20248
20249   if (sw_if_index_set == 0)
20250     {
20251       errmsg ("missing interface name or sw_if_index");
20252       return -99;
20253     }
20254
20255   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20256
20257   mp->sw_if_index = ntohl (sw_if_index);
20258   mp->ip4_table_index = ntohl (ip4_table_index);
20259   mp->ip6_table_index = ntohl (ip6_table_index);
20260   mp->is_add = is_add;
20261
20262   S (mp);
20263   W (ret);
20264   return ret;
20265 }
20266
20267 static int
20268 api_flow_classify_dump (vat_main_t * vam)
20269 {
20270   unformat_input_t *i = vam->input;
20271   vl_api_flow_classify_dump_t *mp;
20272   vl_api_control_ping_t *mp_ping;
20273   u8 type = FLOW_CLASSIFY_N_TABLES;
20274   int ret;
20275
20276   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20277     ;
20278   else
20279     {
20280       errmsg ("classify table type must be specified");
20281       return -99;
20282     }
20283
20284   if (!vam->json_output)
20285     {
20286       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20287     }
20288
20289   M (FLOW_CLASSIFY_DUMP, mp);
20290   mp->type = type;
20291   /* send it... */
20292   S (mp);
20293
20294   /* Use a control ping for synchronization */
20295   MPING (CONTROL_PING, mp_ping);
20296   S (mp_ping);
20297
20298   /* Wait for a reply... */
20299   W (ret);
20300   return ret;
20301 }
20302
20303 static int
20304 api_feature_enable_disable (vat_main_t * vam)
20305 {
20306   unformat_input_t *i = vam->input;
20307   vl_api_feature_enable_disable_t *mp;
20308   u8 *arc_name = 0;
20309   u8 *feature_name = 0;
20310   u32 sw_if_index = ~0;
20311   u8 enable = 1;
20312   int ret;
20313
20314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20315     {
20316       if (unformat (i, "arc_name %s", &arc_name))
20317         ;
20318       else if (unformat (i, "feature_name %s", &feature_name))
20319         ;
20320       else
20321         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20322         ;
20323       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20324         ;
20325       else if (unformat (i, "disable"))
20326         enable = 0;
20327       else
20328         break;
20329     }
20330
20331   if (arc_name == 0)
20332     {
20333       errmsg ("missing arc name");
20334       return -99;
20335     }
20336   if (vec_len (arc_name) > 63)
20337     {
20338       errmsg ("arc name too long");
20339     }
20340
20341   if (feature_name == 0)
20342     {
20343       errmsg ("missing feature name");
20344       return -99;
20345     }
20346   if (vec_len (feature_name) > 63)
20347     {
20348       errmsg ("feature name too long");
20349     }
20350
20351   if (sw_if_index == ~0)
20352     {
20353       errmsg ("missing interface name or sw_if_index");
20354       return -99;
20355     }
20356
20357   /* Construct the API message */
20358   M (FEATURE_ENABLE_DISABLE, mp);
20359   mp->sw_if_index = ntohl (sw_if_index);
20360   mp->enable = enable;
20361   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20362   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20363   vec_free (arc_name);
20364   vec_free (feature_name);
20365
20366   S (mp);
20367   W (ret);
20368   return ret;
20369 }
20370
20371 static int
20372 api_sw_interface_tag_add_del (vat_main_t * vam)
20373 {
20374   unformat_input_t *i = vam->input;
20375   vl_api_sw_interface_tag_add_del_t *mp;
20376   u32 sw_if_index = ~0;
20377   u8 *tag = 0;
20378   u8 enable = 1;
20379   int ret;
20380
20381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20382     {
20383       if (unformat (i, "tag %s", &tag))
20384         ;
20385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20386         ;
20387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20388         ;
20389       else if (unformat (i, "del"))
20390         enable = 0;
20391       else
20392         break;
20393     }
20394
20395   if (sw_if_index == ~0)
20396     {
20397       errmsg ("missing interface name or sw_if_index");
20398       return -99;
20399     }
20400
20401   if (enable && (tag == 0))
20402     {
20403       errmsg ("no tag specified");
20404       return -99;
20405     }
20406
20407   /* Construct the API message */
20408   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20409   mp->sw_if_index = ntohl (sw_if_index);
20410   mp->is_add = enable;
20411   if (enable)
20412     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20413   vec_free (tag);
20414
20415   S (mp);
20416   W (ret);
20417   return ret;
20418 }
20419
20420 static void vl_api_l2_xconnect_details_t_handler
20421   (vl_api_l2_xconnect_details_t * mp)
20422 {
20423   vat_main_t *vam = &vat_main;
20424
20425   print (vam->ofp, "%15d%15d",
20426          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20427 }
20428
20429 static void vl_api_l2_xconnect_details_t_handler_json
20430   (vl_api_l2_xconnect_details_t * mp)
20431 {
20432   vat_main_t *vam = &vat_main;
20433   vat_json_node_t *node = NULL;
20434
20435   if (VAT_JSON_ARRAY != vam->json_tree.type)
20436     {
20437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20438       vat_json_init_array (&vam->json_tree);
20439     }
20440   node = vat_json_array_add (&vam->json_tree);
20441
20442   vat_json_init_object (node);
20443   vat_json_object_add_uint (node, "rx_sw_if_index",
20444                             ntohl (mp->rx_sw_if_index));
20445   vat_json_object_add_uint (node, "tx_sw_if_index",
20446                             ntohl (mp->tx_sw_if_index));
20447 }
20448
20449 static int
20450 api_l2_xconnect_dump (vat_main_t * vam)
20451 {
20452   vl_api_l2_xconnect_dump_t *mp;
20453   vl_api_control_ping_t *mp_ping;
20454   int ret;
20455
20456   if (!vam->json_output)
20457     {
20458       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20459     }
20460
20461   M (L2_XCONNECT_DUMP, mp);
20462
20463   S (mp);
20464
20465   /* Use a control ping for synchronization */
20466   MPING (CONTROL_PING, mp_ping);
20467   S (mp_ping);
20468
20469   W (ret);
20470   return ret;
20471 }
20472
20473 static int
20474 api_hw_interface_set_mtu (vat_main_t * vam)
20475 {
20476   unformat_input_t *i = vam->input;
20477   vl_api_hw_interface_set_mtu_t *mp;
20478   u32 sw_if_index = ~0;
20479   u32 mtu = 0;
20480   int ret;
20481
20482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20483     {
20484       if (unformat (i, "mtu %d", &mtu))
20485         ;
20486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20487         ;
20488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20489         ;
20490       else
20491         break;
20492     }
20493
20494   if (sw_if_index == ~0)
20495     {
20496       errmsg ("missing interface name or sw_if_index");
20497       return -99;
20498     }
20499
20500   if (mtu == 0)
20501     {
20502       errmsg ("no mtu specified");
20503       return -99;
20504     }
20505
20506   /* Construct the API message */
20507   M (HW_INTERFACE_SET_MTU, mp);
20508   mp->sw_if_index = ntohl (sw_if_index);
20509   mp->mtu = ntohs ((u16) mtu);
20510
20511   S (mp);
20512   W (ret);
20513   return ret;
20514 }
20515
20516 static int
20517 api_p2p_ethernet_add (vat_main_t * vam)
20518 {
20519   unformat_input_t *i = vam->input;
20520   vl_api_p2p_ethernet_add_t *mp;
20521   u32 parent_if_index = ~0;
20522   u32 sub_id = ~0;
20523   u8 remote_mac[6];
20524   u8 mac_set = 0;
20525   int ret;
20526
20527   clib_memset (remote_mac, 0, sizeof (remote_mac));
20528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20529     {
20530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20531         ;
20532       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20533         ;
20534       else
20535         if (unformat
20536             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20537         mac_set++;
20538       else if (unformat (i, "sub_id %d", &sub_id))
20539         ;
20540       else
20541         {
20542           clib_warning ("parse error '%U'", format_unformat_error, i);
20543           return -99;
20544         }
20545     }
20546
20547   if (parent_if_index == ~0)
20548     {
20549       errmsg ("missing interface name or sw_if_index");
20550       return -99;
20551     }
20552   if (mac_set == 0)
20553     {
20554       errmsg ("missing remote mac address");
20555       return -99;
20556     }
20557   if (sub_id == ~0)
20558     {
20559       errmsg ("missing sub-interface id");
20560       return -99;
20561     }
20562
20563   M (P2P_ETHERNET_ADD, mp);
20564   mp->parent_if_index = ntohl (parent_if_index);
20565   mp->subif_id = ntohl (sub_id);
20566   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20567
20568   S (mp);
20569   W (ret);
20570   return ret;
20571 }
20572
20573 static int
20574 api_p2p_ethernet_del (vat_main_t * vam)
20575 {
20576   unformat_input_t *i = vam->input;
20577   vl_api_p2p_ethernet_del_t *mp;
20578   u32 parent_if_index = ~0;
20579   u8 remote_mac[6];
20580   u8 mac_set = 0;
20581   int ret;
20582
20583   clib_memset (remote_mac, 0, sizeof (remote_mac));
20584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20585     {
20586       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20587         ;
20588       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20589         ;
20590       else
20591         if (unformat
20592             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20593         mac_set++;
20594       else
20595         {
20596           clib_warning ("parse error '%U'", format_unformat_error, i);
20597           return -99;
20598         }
20599     }
20600
20601   if (parent_if_index == ~0)
20602     {
20603       errmsg ("missing interface name or sw_if_index");
20604       return -99;
20605     }
20606   if (mac_set == 0)
20607     {
20608       errmsg ("missing remote mac address");
20609       return -99;
20610     }
20611
20612   M (P2P_ETHERNET_DEL, mp);
20613   mp->parent_if_index = ntohl (parent_if_index);
20614   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20615
20616   S (mp);
20617   W (ret);
20618   return ret;
20619 }
20620
20621 static int
20622 api_lldp_config (vat_main_t * vam)
20623 {
20624   unformat_input_t *i = vam->input;
20625   vl_api_lldp_config_t *mp;
20626   int tx_hold = 0;
20627   int tx_interval = 0;
20628   u8 *sys_name = NULL;
20629   int ret;
20630
20631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20632     {
20633       if (unformat (i, "system-name %s", &sys_name))
20634         ;
20635       else if (unformat (i, "tx-hold %d", &tx_hold))
20636         ;
20637       else if (unformat (i, "tx-interval %d", &tx_interval))
20638         ;
20639       else
20640         {
20641           clib_warning ("parse error '%U'", format_unformat_error, i);
20642           return -99;
20643         }
20644     }
20645
20646   vec_add1 (sys_name, 0);
20647
20648   M (LLDP_CONFIG, mp);
20649   mp->tx_hold = htonl (tx_hold);
20650   mp->tx_interval = htonl (tx_interval);
20651   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20652   vec_free (sys_name);
20653
20654   S (mp);
20655   W (ret);
20656   return ret;
20657 }
20658
20659 static int
20660 api_sw_interface_set_lldp (vat_main_t * vam)
20661 {
20662   unformat_input_t *i = vam->input;
20663   vl_api_sw_interface_set_lldp_t *mp;
20664   u32 sw_if_index = ~0;
20665   u32 enable = 1;
20666   u8 *port_desc = NULL, *mgmt_oid = NULL;
20667   ip4_address_t ip4_addr;
20668   ip6_address_t ip6_addr;
20669   int ret;
20670
20671   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20672   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20673
20674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20675     {
20676       if (unformat (i, "disable"))
20677         enable = 0;
20678       else
20679         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20680         ;
20681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20682         ;
20683       else if (unformat (i, "port-desc %s", &port_desc))
20684         ;
20685       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20686         ;
20687       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20688         ;
20689       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20690         ;
20691       else
20692         break;
20693     }
20694
20695   if (sw_if_index == ~0)
20696     {
20697       errmsg ("missing interface name or sw_if_index");
20698       return -99;
20699     }
20700
20701   /* Construct the API message */
20702   vec_add1 (port_desc, 0);
20703   vec_add1 (mgmt_oid, 0);
20704   M (SW_INTERFACE_SET_LLDP, mp);
20705   mp->sw_if_index = ntohl (sw_if_index);
20706   mp->enable = enable;
20707   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20708   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20709   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20710   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20711   vec_free (port_desc);
20712   vec_free (mgmt_oid);
20713
20714   S (mp);
20715   W (ret);
20716   return ret;
20717 }
20718
20719 static int
20720 api_tcp_configure_src_addresses (vat_main_t * vam)
20721 {
20722   vl_api_tcp_configure_src_addresses_t *mp;
20723   unformat_input_t *i = vam->input;
20724   ip4_address_t v4first, v4last;
20725   ip6_address_t v6first, v6last;
20726   u8 range_set = 0;
20727   u32 vrf_id = 0;
20728   int ret;
20729
20730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20731     {
20732       if (unformat (i, "%U - %U",
20733                     unformat_ip4_address, &v4first,
20734                     unformat_ip4_address, &v4last))
20735         {
20736           if (range_set)
20737             {
20738               errmsg ("one range per message (range already set)");
20739               return -99;
20740             }
20741           range_set = 1;
20742         }
20743       else if (unformat (i, "%U - %U",
20744                          unformat_ip6_address, &v6first,
20745                          unformat_ip6_address, &v6last))
20746         {
20747           if (range_set)
20748             {
20749               errmsg ("one range per message (range already set)");
20750               return -99;
20751             }
20752           range_set = 2;
20753         }
20754       else if (unformat (i, "vrf %d", &vrf_id))
20755         ;
20756       else
20757         break;
20758     }
20759
20760   if (range_set == 0)
20761     {
20762       errmsg ("address range not set");
20763       return -99;
20764     }
20765
20766   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20767   mp->vrf_id = ntohl (vrf_id);
20768   /* ipv6? */
20769   if (range_set == 2)
20770     {
20771       mp->is_ipv6 = 1;
20772       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20773       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20774     }
20775   else
20776     {
20777       mp->is_ipv6 = 0;
20778       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20779       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20780     }
20781   S (mp);
20782   W (ret);
20783   return ret;
20784 }
20785
20786 static void vl_api_app_namespace_add_del_reply_t_handler
20787   (vl_api_app_namespace_add_del_reply_t * mp)
20788 {
20789   vat_main_t *vam = &vat_main;
20790   i32 retval = ntohl (mp->retval);
20791   if (vam->async_mode)
20792     {
20793       vam->async_errors += (retval < 0);
20794     }
20795   else
20796     {
20797       vam->retval = retval;
20798       if (retval == 0)
20799         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20800       vam->result_ready = 1;
20801     }
20802 }
20803
20804 static void vl_api_app_namespace_add_del_reply_t_handler_json
20805   (vl_api_app_namespace_add_del_reply_t * mp)
20806 {
20807   vat_main_t *vam = &vat_main;
20808   vat_json_node_t node;
20809
20810   vat_json_init_object (&node);
20811   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20812   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20813
20814   vat_json_print (vam->ofp, &node);
20815   vat_json_free (&node);
20816
20817   vam->retval = ntohl (mp->retval);
20818   vam->result_ready = 1;
20819 }
20820
20821 static int
20822 api_app_namespace_add_del (vat_main_t * vam)
20823 {
20824   vl_api_app_namespace_add_del_t *mp;
20825   unformat_input_t *i = vam->input;
20826   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20827   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20828   u64 secret;
20829   int ret;
20830
20831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20832     {
20833       if (unformat (i, "id %_%v%_", &ns_id))
20834         ;
20835       else if (unformat (i, "secret %lu", &secret))
20836         secret_set = 1;
20837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20838         sw_if_index_set = 1;
20839       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20840         ;
20841       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20842         ;
20843       else
20844         break;
20845     }
20846   if (!ns_id || !secret_set || !sw_if_index_set)
20847     {
20848       errmsg ("namespace id, secret and sw_if_index must be set");
20849       return -99;
20850     }
20851   if (vec_len (ns_id) > 64)
20852     {
20853       errmsg ("namespace id too long");
20854       return -99;
20855     }
20856   M (APP_NAMESPACE_ADD_DEL, mp);
20857
20858   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20859   mp->namespace_id_len = vec_len (ns_id);
20860   mp->secret = clib_host_to_net_u64 (secret);
20861   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20862   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20863   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20864   vec_free (ns_id);
20865   S (mp);
20866   W (ret);
20867   return ret;
20868 }
20869
20870 static int
20871 api_sock_init_shm (vat_main_t * vam)
20872 {
20873 #if VPP_API_TEST_BUILTIN == 0
20874   unformat_input_t *i = vam->input;
20875   vl_api_shm_elem_config_t *config = 0;
20876   u64 size = 64 << 20;
20877   int rv;
20878
20879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20880     {
20881       if (unformat (i, "size %U", unformat_memory_size, &size))
20882         ;
20883       else
20884         break;
20885     }
20886
20887   /*
20888    * Canned custom ring allocator config.
20889    * Should probably parse all of this
20890    */
20891   vec_validate (config, 6);
20892   config[0].type = VL_API_VLIB_RING;
20893   config[0].size = 256;
20894   config[0].count = 32;
20895
20896   config[1].type = VL_API_VLIB_RING;
20897   config[1].size = 1024;
20898   config[1].count = 16;
20899
20900   config[2].type = VL_API_VLIB_RING;
20901   config[2].size = 4096;
20902   config[2].count = 2;
20903
20904   config[3].type = VL_API_CLIENT_RING;
20905   config[3].size = 256;
20906   config[3].count = 32;
20907
20908   config[4].type = VL_API_CLIENT_RING;
20909   config[4].size = 1024;
20910   config[4].count = 16;
20911
20912   config[5].type = VL_API_CLIENT_RING;
20913   config[5].size = 4096;
20914   config[5].count = 2;
20915
20916   config[6].type = VL_API_QUEUE;
20917   config[6].count = 128;
20918   config[6].size = sizeof (uword);
20919
20920   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20921   if (!rv)
20922     vam->client_index_invalid = 1;
20923   return rv;
20924 #else
20925   return -99;
20926 #endif
20927 }
20928
20929 static int
20930 api_dns_enable_disable (vat_main_t * vam)
20931 {
20932   unformat_input_t *line_input = vam->input;
20933   vl_api_dns_enable_disable_t *mp;
20934   u8 enable_disable = 1;
20935   int ret;
20936
20937   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20938     {
20939       if (unformat (line_input, "disable"))
20940         enable_disable = 0;
20941       if (unformat (line_input, "enable"))
20942         enable_disable = 1;
20943       else
20944         break;
20945     }
20946
20947   /* Construct the API message */
20948   M (DNS_ENABLE_DISABLE, mp);
20949   mp->enable = enable_disable;
20950
20951   /* send it... */
20952   S (mp);
20953   /* Wait for the reply */
20954   W (ret);
20955   return ret;
20956 }
20957
20958 static int
20959 api_dns_resolve_name (vat_main_t * vam)
20960 {
20961   unformat_input_t *line_input = vam->input;
20962   vl_api_dns_resolve_name_t *mp;
20963   u8 *name = 0;
20964   int ret;
20965
20966   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20967     {
20968       if (unformat (line_input, "%s", &name))
20969         ;
20970       else
20971         break;
20972     }
20973
20974   if (vec_len (name) > 127)
20975     {
20976       errmsg ("name too long");
20977       return -99;
20978     }
20979
20980   /* Construct the API message */
20981   M (DNS_RESOLVE_NAME, mp);
20982   memcpy (mp->name, name, vec_len (name));
20983   vec_free (name);
20984
20985   /* send it... */
20986   S (mp);
20987   /* Wait for the reply */
20988   W (ret);
20989   return ret;
20990 }
20991
20992 static int
20993 api_dns_resolve_ip (vat_main_t * vam)
20994 {
20995   unformat_input_t *line_input = vam->input;
20996   vl_api_dns_resolve_ip_t *mp;
20997   int is_ip6 = -1;
20998   ip4_address_t addr4;
20999   ip6_address_t addr6;
21000   int ret;
21001
21002   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21003     {
21004       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21005         is_ip6 = 1;
21006       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21007         is_ip6 = 0;
21008       else
21009         break;
21010     }
21011
21012   if (is_ip6 == -1)
21013     {
21014       errmsg ("missing address");
21015       return -99;
21016     }
21017
21018   /* Construct the API message */
21019   M (DNS_RESOLVE_IP, mp);
21020   mp->is_ip6 = is_ip6;
21021   if (is_ip6)
21022     memcpy (mp->address, &addr6, sizeof (addr6));
21023   else
21024     memcpy (mp->address, &addr4, sizeof (addr4));
21025
21026   /* send it... */
21027   S (mp);
21028   /* Wait for the reply */
21029   W (ret);
21030   return ret;
21031 }
21032
21033 static int
21034 api_dns_name_server_add_del (vat_main_t * vam)
21035 {
21036   unformat_input_t *i = vam->input;
21037   vl_api_dns_name_server_add_del_t *mp;
21038   u8 is_add = 1;
21039   ip6_address_t ip6_server;
21040   ip4_address_t ip4_server;
21041   int ip6_set = 0;
21042   int ip4_set = 0;
21043   int ret = 0;
21044
21045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21046     {
21047       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21048         ip6_set = 1;
21049       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21050         ip4_set = 1;
21051       else if (unformat (i, "del"))
21052         is_add = 0;
21053       else
21054         {
21055           clib_warning ("parse error '%U'", format_unformat_error, i);
21056           return -99;
21057         }
21058     }
21059
21060   if (ip4_set && ip6_set)
21061     {
21062       errmsg ("Only one server address allowed per message");
21063       return -99;
21064     }
21065   if ((ip4_set + ip6_set) == 0)
21066     {
21067       errmsg ("Server address required");
21068       return -99;
21069     }
21070
21071   /* Construct the API message */
21072   M (DNS_NAME_SERVER_ADD_DEL, mp);
21073
21074   if (ip6_set)
21075     {
21076       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21077       mp->is_ip6 = 1;
21078     }
21079   else
21080     {
21081       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21082       mp->is_ip6 = 0;
21083     }
21084
21085   mp->is_add = is_add;
21086
21087   /* send it... */
21088   S (mp);
21089
21090   /* Wait for a reply, return good/bad news  */
21091   W (ret);
21092   return ret;
21093 }
21094
21095 static void
21096 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21097 {
21098   vat_main_t *vam = &vat_main;
21099
21100   if (mp->is_ip4)
21101     {
21102       print (vam->ofp,
21103              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21104              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21105              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21106              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21107              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21108              clib_net_to_host_u32 (mp->action_index), mp->tag);
21109     }
21110   else
21111     {
21112       print (vam->ofp,
21113              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21114              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21115              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21116              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21117              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21118              clib_net_to_host_u32 (mp->action_index), mp->tag);
21119     }
21120 }
21121
21122 static void
21123 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21124                                              mp)
21125 {
21126   vat_main_t *vam = &vat_main;
21127   vat_json_node_t *node = NULL;
21128   struct in6_addr ip6;
21129   struct in_addr ip4;
21130
21131   if (VAT_JSON_ARRAY != vam->json_tree.type)
21132     {
21133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21134       vat_json_init_array (&vam->json_tree);
21135     }
21136   node = vat_json_array_add (&vam->json_tree);
21137   vat_json_init_object (node);
21138
21139   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21140   vat_json_object_add_uint (node, "appns_index",
21141                             clib_net_to_host_u32 (mp->appns_index));
21142   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21143   vat_json_object_add_uint (node, "scope", mp->scope);
21144   vat_json_object_add_uint (node, "action_index",
21145                             clib_net_to_host_u32 (mp->action_index));
21146   vat_json_object_add_uint (node, "lcl_port",
21147                             clib_net_to_host_u16 (mp->lcl_port));
21148   vat_json_object_add_uint (node, "rmt_port",
21149                             clib_net_to_host_u16 (mp->rmt_port));
21150   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21151   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21152   vat_json_object_add_string_copy (node, "tag", mp->tag);
21153   if (mp->is_ip4)
21154     {
21155       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21156       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21157       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21158       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21159     }
21160   else
21161     {
21162       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21163       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21164       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21165       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21166     }
21167 }
21168
21169 static int
21170 api_session_rule_add_del (vat_main_t * vam)
21171 {
21172   vl_api_session_rule_add_del_t *mp;
21173   unformat_input_t *i = vam->input;
21174   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21175   u32 appns_index = 0, scope = 0;
21176   ip4_address_t lcl_ip4, rmt_ip4;
21177   ip6_address_t lcl_ip6, rmt_ip6;
21178   u8 is_ip4 = 1, conn_set = 0;
21179   u8 is_add = 1, *tag = 0;
21180   int ret;
21181
21182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21183     {
21184       if (unformat (i, "del"))
21185         is_add = 0;
21186       else if (unformat (i, "add"))
21187         ;
21188       else if (unformat (i, "proto tcp"))
21189         proto = 0;
21190       else if (unformat (i, "proto udp"))
21191         proto = 1;
21192       else if (unformat (i, "appns %d", &appns_index))
21193         ;
21194       else if (unformat (i, "scope %d", &scope))
21195         ;
21196       else if (unformat (i, "tag %_%v%_", &tag))
21197         ;
21198       else
21199         if (unformat
21200             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21201              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21202              &rmt_port))
21203         {
21204           is_ip4 = 1;
21205           conn_set = 1;
21206         }
21207       else
21208         if (unformat
21209             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21210              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21211              &rmt_port))
21212         {
21213           is_ip4 = 0;
21214           conn_set = 1;
21215         }
21216       else if (unformat (i, "action %d", &action))
21217         ;
21218       else
21219         break;
21220     }
21221   if (proto == ~0 || !conn_set || action == ~0)
21222     {
21223       errmsg ("transport proto, connection and action must be set");
21224       return -99;
21225     }
21226
21227   if (scope > 3)
21228     {
21229       errmsg ("scope should be 0-3");
21230       return -99;
21231     }
21232
21233   M (SESSION_RULE_ADD_DEL, mp);
21234
21235   mp->is_ip4 = is_ip4;
21236   mp->transport_proto = proto;
21237   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21238   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21239   mp->lcl_plen = lcl_plen;
21240   mp->rmt_plen = rmt_plen;
21241   mp->action_index = clib_host_to_net_u32 (action);
21242   mp->appns_index = clib_host_to_net_u32 (appns_index);
21243   mp->scope = scope;
21244   mp->is_add = is_add;
21245   if (is_ip4)
21246     {
21247       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21248       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21249     }
21250   else
21251     {
21252       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21253       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21254     }
21255   if (tag)
21256     {
21257       clib_memcpy (mp->tag, tag, vec_len (tag));
21258       vec_free (tag);
21259     }
21260
21261   S (mp);
21262   W (ret);
21263   return ret;
21264 }
21265
21266 static int
21267 api_session_rules_dump (vat_main_t * vam)
21268 {
21269   vl_api_session_rules_dump_t *mp;
21270   vl_api_control_ping_t *mp_ping;
21271   int ret;
21272
21273   if (!vam->json_output)
21274     {
21275       print (vam->ofp, "%=20s", "Session Rules");
21276     }
21277
21278   M (SESSION_RULES_DUMP, mp);
21279   /* send it... */
21280   S (mp);
21281
21282   /* Use a control ping for synchronization */
21283   MPING (CONTROL_PING, mp_ping);
21284   S (mp_ping);
21285
21286   /* Wait for a reply... */
21287   W (ret);
21288   return ret;
21289 }
21290
21291 static int
21292 api_ip_container_proxy_add_del (vat_main_t * vam)
21293 {
21294   vl_api_ip_container_proxy_add_del_t *mp;
21295   unformat_input_t *i = vam->input;
21296   u32 sw_if_index = ~0;
21297   vl_api_prefix_t pfx = { };
21298   u8 is_add = 1;
21299   int ret;
21300
21301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21302     {
21303       if (unformat (i, "del"))
21304         is_add = 0;
21305       else if (unformat (i, "add"))
21306         ;
21307       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21308         ;
21309       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21310         ;
21311       else
21312         break;
21313     }
21314   if (sw_if_index == ~0 || pfx.address_length == 0)
21315     {
21316       errmsg ("address and sw_if_index must be set");
21317       return -99;
21318     }
21319
21320   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21321
21322   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21323   mp->is_add = is_add;
21324   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21325
21326   S (mp);
21327   W (ret);
21328   return ret;
21329 }
21330
21331 static int
21332 api_qos_record_enable_disable (vat_main_t * vam)
21333 {
21334   unformat_input_t *i = vam->input;
21335   vl_api_qos_record_enable_disable_t *mp;
21336   u32 sw_if_index, qs = 0xff;
21337   u8 sw_if_index_set = 0;
21338   u8 enable = 1;
21339   int ret;
21340
21341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21342     {
21343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21344         sw_if_index_set = 1;
21345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21346         sw_if_index_set = 1;
21347       else if (unformat (i, "%U", unformat_qos_source, &qs))
21348         ;
21349       else if (unformat (i, "disable"))
21350         enable = 0;
21351       else
21352         {
21353           clib_warning ("parse error '%U'", format_unformat_error, i);
21354           return -99;
21355         }
21356     }
21357
21358   if (sw_if_index_set == 0)
21359     {
21360       errmsg ("missing interface name or sw_if_index");
21361       return -99;
21362     }
21363   if (qs == 0xff)
21364     {
21365       errmsg ("input location must be specified");
21366       return -99;
21367     }
21368
21369   M (QOS_RECORD_ENABLE_DISABLE, mp);
21370
21371   mp->sw_if_index = ntohl (sw_if_index);
21372   mp->input_source = qs;
21373   mp->enable = enable;
21374
21375   S (mp);
21376   W (ret);
21377   return ret;
21378 }
21379
21380
21381 static int
21382 q_or_quit (vat_main_t * vam)
21383 {
21384 #if VPP_API_TEST_BUILTIN == 0
21385   longjmp (vam->jump_buf, 1);
21386 #endif
21387   return 0;                     /* not so much */
21388 }
21389
21390 static int
21391 q (vat_main_t * vam)
21392 {
21393   return q_or_quit (vam);
21394 }
21395
21396 static int
21397 quit (vat_main_t * vam)
21398 {
21399   return q_or_quit (vam);
21400 }
21401
21402 static int
21403 comment (vat_main_t * vam)
21404 {
21405   return 0;
21406 }
21407
21408 static int
21409 statseg (vat_main_t * vam)
21410 {
21411   ssvm_private_t *ssvmp = &vam->stat_segment;
21412   ssvm_shared_header_t *shared_header = ssvmp->sh;
21413   vlib_counter_t **counters;
21414   u64 thread0_index1_packets;
21415   u64 thread0_index1_bytes;
21416   f64 vector_rate, input_rate;
21417   uword *p;
21418
21419   uword *counter_vector_by_name;
21420   if (vam->stat_segment_lockp == 0)
21421     {
21422       errmsg ("Stat segment not mapped...");
21423       return -99;
21424     }
21425
21426   /* look up "/if/rx for sw_if_index 1 as a test */
21427
21428   clib_spinlock_lock (vam->stat_segment_lockp);
21429
21430   counter_vector_by_name = (uword *) shared_header->opaque[1];
21431
21432   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21433   if (p == 0)
21434     {
21435       clib_spinlock_unlock (vam->stat_segment_lockp);
21436       errmsg ("/if/tx not found?");
21437       return -99;
21438     }
21439
21440   /* Fish per-thread vector of combined counters from shared memory */
21441   counters = (vlib_counter_t **) p[0];
21442
21443   if (vec_len (counters[0]) < 2)
21444     {
21445       clib_spinlock_unlock (vam->stat_segment_lockp);
21446       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21447       return -99;
21448     }
21449
21450   /* Read thread 0 sw_if_index 1 counter */
21451   thread0_index1_packets = counters[0][1].packets;
21452   thread0_index1_bytes = counters[0][1].bytes;
21453
21454   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21455   if (p == 0)
21456     {
21457       clib_spinlock_unlock (vam->stat_segment_lockp);
21458       errmsg ("vector_rate not found?");
21459       return -99;
21460     }
21461
21462   vector_rate = *(f64 *) (p[0]);
21463   p = hash_get_mem (counter_vector_by_name, "input_rate");
21464   if (p == 0)
21465     {
21466       clib_spinlock_unlock (vam->stat_segment_lockp);
21467       errmsg ("input_rate not found?");
21468       return -99;
21469     }
21470   input_rate = *(f64 *) (p[0]);
21471
21472   clib_spinlock_unlock (vam->stat_segment_lockp);
21473
21474   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21475          vector_rate, input_rate);
21476   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21477          thread0_index1_packets, thread0_index1_bytes);
21478
21479   return 0;
21480 }
21481
21482 static int
21483 cmd_cmp (void *a1, void *a2)
21484 {
21485   u8 **c1 = a1;
21486   u8 **c2 = a2;
21487
21488   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21489 }
21490
21491 static int
21492 help (vat_main_t * vam)
21493 {
21494   u8 **cmds = 0;
21495   u8 *name = 0;
21496   hash_pair_t *p;
21497   unformat_input_t *i = vam->input;
21498   int j;
21499
21500   if (unformat (i, "%s", &name))
21501     {
21502       uword *hs;
21503
21504       vec_add1 (name, 0);
21505
21506       hs = hash_get_mem (vam->help_by_name, name);
21507       if (hs)
21508         print (vam->ofp, "usage: %s %s", name, hs[0]);
21509       else
21510         print (vam->ofp, "No such msg / command '%s'", name);
21511       vec_free (name);
21512       return 0;
21513     }
21514
21515   print (vam->ofp, "Help is available for the following:");
21516
21517     /* *INDENT-OFF* */
21518     hash_foreach_pair (p, vam->function_by_name,
21519     ({
21520       vec_add1 (cmds, (u8 *)(p->key));
21521     }));
21522     /* *INDENT-ON* */
21523
21524   vec_sort_with_function (cmds, cmd_cmp);
21525
21526   for (j = 0; j < vec_len (cmds); j++)
21527     print (vam->ofp, "%s", cmds[j]);
21528
21529   vec_free (cmds);
21530   return 0;
21531 }
21532
21533 static int
21534 set (vat_main_t * vam)
21535 {
21536   u8 *name = 0, *value = 0;
21537   unformat_input_t *i = vam->input;
21538
21539   if (unformat (i, "%s", &name))
21540     {
21541       /* The input buffer is a vector, not a string. */
21542       value = vec_dup (i->buffer);
21543       vec_delete (value, i->index, 0);
21544       /* Almost certainly has a trailing newline */
21545       if (value[vec_len (value) - 1] == '\n')
21546         value[vec_len (value) - 1] = 0;
21547       /* Make sure it's a proper string, one way or the other */
21548       vec_add1 (value, 0);
21549       (void) clib_macro_set_value (&vam->macro_main,
21550                                    (char *) name, (char *) value);
21551     }
21552   else
21553     errmsg ("usage: set <name> <value>");
21554
21555   vec_free (name);
21556   vec_free (value);
21557   return 0;
21558 }
21559
21560 static int
21561 unset (vat_main_t * vam)
21562 {
21563   u8 *name = 0;
21564
21565   if (unformat (vam->input, "%s", &name))
21566     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21567       errmsg ("unset: %s wasn't set", name);
21568   vec_free (name);
21569   return 0;
21570 }
21571
21572 typedef struct
21573 {
21574   u8 *name;
21575   u8 *value;
21576 } macro_sort_t;
21577
21578
21579 static int
21580 macro_sort_cmp (void *a1, void *a2)
21581 {
21582   macro_sort_t *s1 = a1;
21583   macro_sort_t *s2 = a2;
21584
21585   return strcmp ((char *) (s1->name), (char *) (s2->name));
21586 }
21587
21588 static int
21589 dump_macro_table (vat_main_t * vam)
21590 {
21591   macro_sort_t *sort_me = 0, *sm;
21592   int i;
21593   hash_pair_t *p;
21594
21595     /* *INDENT-OFF* */
21596     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21597     ({
21598       vec_add2 (sort_me, sm, 1);
21599       sm->name = (u8 *)(p->key);
21600       sm->value = (u8 *) (p->value[0]);
21601     }));
21602     /* *INDENT-ON* */
21603
21604   vec_sort_with_function (sort_me, macro_sort_cmp);
21605
21606   if (vec_len (sort_me))
21607     print (vam->ofp, "%-15s%s", "Name", "Value");
21608   else
21609     print (vam->ofp, "The macro table is empty...");
21610
21611   for (i = 0; i < vec_len (sort_me); i++)
21612     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21613   return 0;
21614 }
21615
21616 static int
21617 dump_node_table (vat_main_t * vam)
21618 {
21619   int i, j;
21620   vlib_node_t *node, *next_node;
21621
21622   if (vec_len (vam->graph_nodes) == 0)
21623     {
21624       print (vam->ofp, "Node table empty, issue get_node_graph...");
21625       return 0;
21626     }
21627
21628   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21629     {
21630       node = vam->graph_nodes[0][i];
21631       print (vam->ofp, "[%d] %s", i, node->name);
21632       for (j = 0; j < vec_len (node->next_nodes); j++)
21633         {
21634           if (node->next_nodes[j] != ~0)
21635             {
21636               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21637               print (vam->ofp, "  [%d] %s", j, next_node->name);
21638             }
21639         }
21640     }
21641   return 0;
21642 }
21643
21644 static int
21645 value_sort_cmp (void *a1, void *a2)
21646 {
21647   name_sort_t *n1 = a1;
21648   name_sort_t *n2 = a2;
21649
21650   if (n1->value < n2->value)
21651     return -1;
21652   if (n1->value > n2->value)
21653     return 1;
21654   return 0;
21655 }
21656
21657
21658 static int
21659 dump_msg_api_table (vat_main_t * vam)
21660 {
21661   api_main_t *am = &api_main;
21662   name_sort_t *nses = 0, *ns;
21663   hash_pair_t *hp;
21664   int i;
21665
21666   /* *INDENT-OFF* */
21667   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21668   ({
21669     vec_add2 (nses, ns, 1);
21670     ns->name = (u8 *)(hp->key);
21671     ns->value = (u32) hp->value[0];
21672   }));
21673   /* *INDENT-ON* */
21674
21675   vec_sort_with_function (nses, value_sort_cmp);
21676
21677   for (i = 0; i < vec_len (nses); i++)
21678     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21679   vec_free (nses);
21680   return 0;
21681 }
21682
21683 static int
21684 get_msg_id (vat_main_t * vam)
21685 {
21686   u8 *name_and_crc;
21687   u32 message_index;
21688
21689   if (unformat (vam->input, "%s", &name_and_crc))
21690     {
21691       message_index = vl_msg_api_get_msg_index (name_and_crc);
21692       if (message_index == ~0)
21693         {
21694           print (vam->ofp, " '%s' not found", name_and_crc);
21695           return 0;
21696         }
21697       print (vam->ofp, " '%s' has message index %d",
21698              name_and_crc, message_index);
21699       return 0;
21700     }
21701   errmsg ("name_and_crc required...");
21702   return 0;
21703 }
21704
21705 static int
21706 search_node_table (vat_main_t * vam)
21707 {
21708   unformat_input_t *line_input = vam->input;
21709   u8 *node_to_find;
21710   int j;
21711   vlib_node_t *node, *next_node;
21712   uword *p;
21713
21714   if (vam->graph_node_index_by_name == 0)
21715     {
21716       print (vam->ofp, "Node table empty, issue get_node_graph...");
21717       return 0;
21718     }
21719
21720   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21721     {
21722       if (unformat (line_input, "%s", &node_to_find))
21723         {
21724           vec_add1 (node_to_find, 0);
21725           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21726           if (p == 0)
21727             {
21728               print (vam->ofp, "%s not found...", node_to_find);
21729               goto out;
21730             }
21731           node = vam->graph_nodes[0][p[0]];
21732           print (vam->ofp, "[%d] %s", p[0], node->name);
21733           for (j = 0; j < vec_len (node->next_nodes); j++)
21734             {
21735               if (node->next_nodes[j] != ~0)
21736                 {
21737                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21738                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21739                 }
21740             }
21741         }
21742
21743       else
21744         {
21745           clib_warning ("parse error '%U'", format_unformat_error,
21746                         line_input);
21747           return -99;
21748         }
21749
21750     out:
21751       vec_free (node_to_find);
21752
21753     }
21754
21755   return 0;
21756 }
21757
21758
21759 static int
21760 script (vat_main_t * vam)
21761 {
21762 #if (VPP_API_TEST_BUILTIN==0)
21763   u8 *s = 0;
21764   char *save_current_file;
21765   unformat_input_t save_input;
21766   jmp_buf save_jump_buf;
21767   u32 save_line_number;
21768
21769   FILE *new_fp, *save_ifp;
21770
21771   if (unformat (vam->input, "%s", &s))
21772     {
21773       new_fp = fopen ((char *) s, "r");
21774       if (new_fp == 0)
21775         {
21776           errmsg ("Couldn't open script file %s", s);
21777           vec_free (s);
21778           return -99;
21779         }
21780     }
21781   else
21782     {
21783       errmsg ("Missing script name");
21784       return -99;
21785     }
21786
21787   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21788   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21789   save_ifp = vam->ifp;
21790   save_line_number = vam->input_line_number;
21791   save_current_file = (char *) vam->current_file;
21792
21793   vam->input_line_number = 0;
21794   vam->ifp = new_fp;
21795   vam->current_file = s;
21796   do_one_file (vam);
21797
21798   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21799   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21800   vam->ifp = save_ifp;
21801   vam->input_line_number = save_line_number;
21802   vam->current_file = (u8 *) save_current_file;
21803   vec_free (s);
21804
21805   return 0;
21806 #else
21807   clib_warning ("use the exec command...");
21808   return -99;
21809 #endif
21810 }
21811
21812 static int
21813 echo (vat_main_t * vam)
21814 {
21815   print (vam->ofp, "%v", vam->input->buffer);
21816   return 0;
21817 }
21818
21819 /* List of API message constructors, CLI names map to api_xxx */
21820 #define foreach_vpe_api_msg                                             \
21821 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21822 _(sw_interface_dump,"")                                                 \
21823 _(sw_interface_set_flags,                                               \
21824   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21825 _(sw_interface_add_del_address,                                         \
21826   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21827 _(sw_interface_set_rx_mode,                                             \
21828   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21829 _(sw_interface_set_rx_placement,                                        \
21830   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21831 _(sw_interface_rx_placement_dump,                                       \
21832   "[<intfc> | sw_if_index <id>]")                                         \
21833 _(sw_interface_set_table,                                               \
21834   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21835 _(sw_interface_set_mpls_enable,                                         \
21836   "<intfc> | sw_if_index [disable | dis]")                              \
21837 _(sw_interface_set_vpath,                                               \
21838   "<intfc> | sw_if_index <id> enable | disable")                        \
21839 _(sw_interface_set_vxlan_bypass,                                        \
21840   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21841 _(sw_interface_set_geneve_bypass,                                       \
21842   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21843 _(sw_interface_set_l2_xconnect,                                         \
21844   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21845   "enable | disable")                                                   \
21846 _(sw_interface_set_l2_bridge,                                           \
21847   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21848   "[shg <split-horizon-group>] [bvi]\n"                                 \
21849   "enable | disable")                                                   \
21850 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21851 _(bridge_domain_add_del,                                                \
21852   "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") \
21853 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21854 _(l2fib_add_del,                                                        \
21855   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21856 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21857 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21858 _(l2_flags,                                                             \
21859   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21860 _(bridge_flags,                                                         \
21861   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21862 _(tap_create_v2,                                                        \
21863   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21864 _(tap_delete_v2,                                                        \
21865   "<vpp-if-name> | sw_if_index <id>")                                   \
21866 _(sw_interface_tap_v2_dump, "")                                         \
21867 _(virtio_pci_create,                                                    \
21868   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21869 _(virtio_pci_delete,                                                    \
21870   "<vpp-if-name> | sw_if_index <id>")                                   \
21871 _(sw_interface_virtio_pci_dump, "")                                     \
21872 _(bond_create,                                                          \
21873   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21874   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21875   "[id <if-id>]")                                                       \
21876 _(bond_delete,                                                          \
21877   "<vpp-if-name> | sw_if_index <id>")                                   \
21878 _(bond_enslave,                                                         \
21879   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21880 _(bond_detach_slave,                                                    \
21881   "sw_if_index <n>")                                                    \
21882 _(sw_interface_bond_dump, "")                                           \
21883 _(sw_interface_slave_dump,                                              \
21884   "<vpp-if-name> | sw_if_index <id>")                                   \
21885 _(ip_table_add_del,                                                     \
21886   "table <n> [ipv6] [add | del]\n")                                     \
21887 _(ip_route_add_del,                                                     \
21888   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21889   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21890   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21891   "[multipath] [count <n>] [del]")                                      \
21892 _(ip_mroute_add_del,                                                    \
21893   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21894   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21895 _(mpls_table_add_del,                                                   \
21896   "table <n> [add | del]\n")                                            \
21897 _(mpls_route_add_del,                                                   \
21898   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21899   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21900   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21901   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21902   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21903   "[count <n>] [del]")                                                  \
21904 _(mpls_ip_bind_unbind,                                                  \
21905   "<label> <addr/len>")                                                 \
21906 _(mpls_tunnel_add_del,                                                  \
21907   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21908   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21909   "[l2-only]  [out-label <n>]")                                         \
21910 _(sr_mpls_policy_add,                                                   \
21911   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21912 _(sr_mpls_policy_del,                                                   \
21913   "bsid <id>")                                                          \
21914 _(bier_table_add_del,                                                   \
21915   "<label> <sub-domain> <set> <bsl> [del]")                             \
21916 _(bier_route_add_del,                                                   \
21917   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21918   "[<intfc> | sw_if_index <id>]"                                        \
21919   "[weight <n>] [del] [multipath]")                                     \
21920 _(proxy_arp_add_del,                                                    \
21921   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21922 _(proxy_arp_intfc_enable_disable,                                       \
21923   "<intfc> | sw_if_index <id> enable | disable")                        \
21924 _(sw_interface_set_unnumbered,                                          \
21925   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21926 _(ip_neighbor_add_del,                                                  \
21927   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21928   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21929 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21930 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21931   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21932   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21933   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21934 _(reset_fib, "vrf <n> [ipv6]")                                          \
21935 _(dhcp_proxy_config,                                                    \
21936   "svr <v46-address> src <v46-address>\n"                               \
21937    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21938 _(dhcp_proxy_set_vss,                                                   \
21939   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21940 _(dhcp_proxy_dump, "ip6")                                               \
21941 _(dhcp_client_config,                                                   \
21942   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21943 _(set_ip_flow_hash,                                                     \
21944   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21945 _(sw_interface_ip6_enable_disable,                                      \
21946   "<intfc> | sw_if_index <id> enable | disable")                        \
21947 _(ip6nd_proxy_add_del,                                                  \
21948   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21949 _(ip6nd_proxy_dump, "")                                                 \
21950 _(sw_interface_ip6nd_ra_prefix,                                         \
21951   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21952   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21953   "[nolink] [isno]")                                                    \
21954 _(sw_interface_ip6nd_ra_config,                                         \
21955   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21956   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21957   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21958 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21959 _(l2_patch_add_del,                                                     \
21960   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21961   "enable | disable")                                                   \
21962 _(sr_localsid_add_del,                                                  \
21963   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21964   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21965 _(classify_add_del_table,                                               \
21966   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21967   " [del] [del-chain] mask <mask-value>\n"                              \
21968   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21969   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21970 _(classify_add_del_session,                                             \
21971   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21972   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21973   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21974   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21975 _(classify_set_interface_ip_table,                                      \
21976   "<intfc> | sw_if_index <nn> table <nn>")                              \
21977 _(classify_set_interface_l2_tables,                                     \
21978   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21979   "  [other-table <nn>]")                                               \
21980 _(get_node_index, "node <node-name")                                    \
21981 _(add_node_next, "node <node-name> next <next-node-name>")              \
21982 _(l2tpv3_create_tunnel,                                                 \
21983   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21984   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21985   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21986 _(l2tpv3_set_tunnel_cookies,                                            \
21987   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21988   "[new_remote_cookie <nn>]\n")                                         \
21989 _(l2tpv3_interface_enable_disable,                                      \
21990   "<intfc> | sw_if_index <nn> enable | disable")                        \
21991 _(l2tpv3_set_lookup_key,                                                \
21992   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21993 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21994 _(vxlan_offload_rx,                                                     \
21995   "hw { <interface name> | hw_if_index <nn>} "                          \
21996   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21997 _(vxlan_add_del_tunnel,                                                 \
21998   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21999   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22000   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22001 _(geneve_add_del_tunnel,                                                \
22002   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22003   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22004   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22005 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22006 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22007 _(gre_tunnel_add_del,                                                   \
22008   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22009   "[teb | erspan <session-id>] [del]")                                  \
22010 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22011 _(l2_fib_clear_table, "")                                               \
22012 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22013 _(l2_interface_vlan_tag_rewrite,                                        \
22014   "<intfc> | sw_if_index <nn> \n"                                       \
22015   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22016   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22017 _(create_vhost_user_if,                                                 \
22018         "socket <filename> [server] [renumber <dev_instance>] "         \
22019         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22020         "[mac <mac_address>]")                                          \
22021 _(modify_vhost_user_if,                                                 \
22022         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22023         "[server] [renumber <dev_instance>]")                           \
22024 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22025 _(sw_interface_vhost_user_dump, "")                                     \
22026 _(show_version, "")                                                     \
22027 _(show_threads, "")                                                     \
22028 _(vxlan_gpe_add_del_tunnel,                                             \
22029   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22030   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22031   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22032   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22033 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22034 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22035 _(interface_name_renumber,                                              \
22036   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22037 _(input_acl_set_interface,                                              \
22038   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22039   "  [l2-table <nn>] [del]")                                            \
22040 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22041 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22042   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22043 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22044 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22045 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22046 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22047 _(ip_dump, "ipv4 | ipv6")                                               \
22048 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22049 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22050   "  spid_id <n> ")                                                     \
22051 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22052   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22053   "  integ_alg <alg> integ_key <hex>")                                  \
22054 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22055   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22056   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22057   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22058 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22059   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22060   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22061   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22062   "  [instance <n>]")     \
22063 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22064 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22065 _(delete_loopback,"sw_if_index <nn>")                                   \
22066 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22067 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22068 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22069 _(want_interface_events,  "enable|disable")                             \
22070 _(get_first_msg_id, "client <name>")                                    \
22071 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22072 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22073   "fib-id <nn> [ip4][ip6][default]")                                    \
22074 _(get_node_graph, " ")                                                  \
22075 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22076 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22077 _(ioam_disable, "")                                                     \
22078 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22079                             " sw_if_index <sw_if_index> p <priority> "  \
22080                             "w <weight>] [del]")                        \
22081 _(one_add_del_locator, "locator-set <locator_name> "                    \
22082                         "iface <intf> | sw_if_index <sw_if_index> "     \
22083                         "p <priority> w <weight> [del]")                \
22084 _(one_add_del_local_eid,"vni <vni> eid "                                \
22085                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22086                          "locator-set <locator_name> [del]"             \
22087                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22088 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22089 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22090 _(one_enable_disable, "enable|disable")                                 \
22091 _(one_map_register_enable_disable, "enable|disable")                    \
22092 _(one_map_register_fallback_threshold, "<value>")                       \
22093 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22094 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22095                                "[seid <seid>] "                         \
22096                                "rloc <locator> p <prio> "               \
22097                                "w <weight> [rloc <loc> ... ] "          \
22098                                "action <action> [del-all]")             \
22099 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22100                           "<local-eid>")                                \
22101 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22102 _(one_use_petr, "ip-address> | disable")                                \
22103 _(one_map_request_mode, "src-dst|dst-only")                             \
22104 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22105 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22106 _(one_locator_set_dump, "[local | remote]")                             \
22107 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22108 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22109                        "[local] | [remote]")                            \
22110 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22111 _(one_ndp_bd_get, "")                                                   \
22112 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22113 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22114 _(one_l2_arp_bd_get, "")                                                \
22115 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22116 _(one_stats_enable_disable, "enable|disable")                           \
22117 _(show_one_stats_enable_disable, "")                                    \
22118 _(one_eid_table_vni_dump, "")                                           \
22119 _(one_eid_table_map_dump, "l2|l3")                                      \
22120 _(one_map_resolver_dump, "")                                            \
22121 _(one_map_server_dump, "")                                              \
22122 _(one_adjacencies_get, "vni <vni>")                                     \
22123 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22124 _(show_one_rloc_probe_state, "")                                        \
22125 _(show_one_map_register_state, "")                                      \
22126 _(show_one_status, "")                                                  \
22127 _(one_stats_dump, "")                                                   \
22128 _(one_stats_flush, "")                                                  \
22129 _(one_get_map_request_itr_rlocs, "")                                    \
22130 _(one_map_register_set_ttl, "<ttl>")                                    \
22131 _(one_set_transport_protocol, "udp|api")                                \
22132 _(one_get_transport_protocol, "")                                       \
22133 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22134 _(one_show_xtr_mode, "")                                                \
22135 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22136 _(one_show_pitr_mode, "")                                               \
22137 _(one_enable_disable_petr_mode, "enable|disable")                       \
22138 _(one_show_petr_mode, "")                                               \
22139 _(show_one_nsh_mapping, "")                                             \
22140 _(show_one_pitr, "")                                                    \
22141 _(show_one_use_petr, "")                                                \
22142 _(show_one_map_request_mode, "")                                        \
22143 _(show_one_map_register_ttl, "")                                        \
22144 _(show_one_map_register_fallback_threshold, "")                         \
22145 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22146                             " sw_if_index <sw_if_index> p <priority> "  \
22147                             "w <weight>] [del]")                        \
22148 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22149                         "iface <intf> | sw_if_index <sw_if_index> "     \
22150                         "p <priority> w <weight> [del]")                \
22151 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22152                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22153                          "locator-set <locator_name> [del]"             \
22154                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22155 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22156 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22157 _(lisp_enable_disable, "enable|disable")                                \
22158 _(lisp_map_register_enable_disable, "enable|disable")                   \
22159 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22160 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22161                                "[seid <seid>] "                         \
22162                                "rloc <locator> p <prio> "               \
22163                                "w <weight> [rloc <loc> ... ] "          \
22164                                "action <action> [del-all]")             \
22165 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22166                           "<local-eid>")                                \
22167 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22168 _(lisp_use_petr, "<ip-address> | disable")                              \
22169 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22170 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22171 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22172 _(lisp_locator_set_dump, "[local | remote]")                            \
22173 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22174 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22175                        "[local] | [remote]")                            \
22176 _(lisp_eid_table_vni_dump, "")                                          \
22177 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22178 _(lisp_map_resolver_dump, "")                                           \
22179 _(lisp_map_server_dump, "")                                             \
22180 _(lisp_adjacencies_get, "vni <vni>")                                    \
22181 _(gpe_fwd_entry_vnis_get, "")                                           \
22182 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22183 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22184                                 "[table <table-id>]")                   \
22185 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22186 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22187 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22188 _(gpe_get_encap_mode, "")                                               \
22189 _(lisp_gpe_add_del_iface, "up|down")                                    \
22190 _(lisp_gpe_enable_disable, "enable|disable")                            \
22191 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22192   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22193 _(show_lisp_rloc_probe_state, "")                                       \
22194 _(show_lisp_map_register_state, "")                                     \
22195 _(show_lisp_status, "")                                                 \
22196 _(lisp_get_map_request_itr_rlocs, "")                                   \
22197 _(show_lisp_pitr, "")                                                   \
22198 _(show_lisp_use_petr, "")                                               \
22199 _(show_lisp_map_request_mode, "")                                       \
22200 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22201 _(af_packet_delete, "name <host interface name>")                       \
22202 _(af_packet_dump, "")                                                   \
22203 _(policer_add_del, "name <policer name> <params> [del]")                \
22204 _(policer_dump, "[name <policer name>]")                                \
22205 _(policer_classify_set_interface,                                       \
22206   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22207   "  [l2-table <nn>] [del]")                                            \
22208 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22209 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22210     "[master|slave]")                                                   \
22211 _(netmap_delete, "name <interface name>")                               \
22212 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22213 _(mpls_table_dump, "")                                                  \
22214 _(mpls_route_dump, "table-id <ID>")                                     \
22215 _(classify_table_ids, "")                                               \
22216 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22217 _(classify_table_info, "table_id <nn>")                                 \
22218 _(classify_session_dump, "table_id <nn>")                               \
22219 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22220     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22221     "[template_interval <nn>] [udp_checksum]")                          \
22222 _(ipfix_exporter_dump, "")                                              \
22223 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22224 _(ipfix_classify_stream_dump, "")                                       \
22225 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22226 _(ipfix_classify_table_dump, "")                                        \
22227 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22228 _(sw_interface_span_dump, "[l2]")                                           \
22229 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22230 _(pg_create_interface, "if_id <nn>")                                    \
22231 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22232 _(pg_enable_disable, "[stream <id>] disable")                           \
22233 _(ip_source_and_port_range_check_add_del,                               \
22234   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22235 _(ip_source_and_port_range_check_interface_add_del,                     \
22236   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22237   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22238 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22239 _(l2_interface_pbb_tag_rewrite,                                         \
22240   "<intfc> | sw_if_index <nn> \n"                                       \
22241   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22242   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22243 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22244 _(flow_classify_set_interface,                                          \
22245   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22246 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22247 _(ip_table_dump, "")                                                    \
22248 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22249 _(ip_mtable_dump, "")                                                   \
22250 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22251 _(feature_enable_disable, "arc_name <arc_name> "                        \
22252   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22253 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22254 "[disable]")                                                            \
22255 _(l2_xconnect_dump, "")                                                 \
22256 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22257 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22258 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22259 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22260 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22261 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22262 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22263   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22264 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22265 _(sock_init_shm, "size <nnn>")                                          \
22266 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22267 _(dns_enable_disable, "[enable][disable]")                              \
22268 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22269 _(dns_resolve_name, "<hostname>")                                       \
22270 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22271 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22272 _(dns_resolve_name, "<hostname>")                                       \
22273 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22274   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22275 _(session_rules_dump, "")                                               \
22276 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22277 _(output_acl_set_interface,                                             \
22278   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22279   "  [l2-table <nn>] [del]")                                            \
22280 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22281
22282 /* List of command functions, CLI names map directly to functions */
22283 #define foreach_cli_function                                    \
22284 _(comment, "usage: comment <ignore-rest-of-line>")              \
22285 _(dump_interface_table, "usage: dump_interface_table")          \
22286 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22287 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22288 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22289 _(dump_macro_table, "usage: dump_macro_table ")                 \
22290 _(dump_node_table, "usage: dump_node_table")                    \
22291 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22292 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22293 _(echo, "usage: echo <message>")                                \
22294 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22295 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22296 _(help, "usage: help")                                          \
22297 _(q, "usage: quit")                                             \
22298 _(quit, "usage: quit")                                          \
22299 _(search_node_table, "usage: search_node_table <name>...")      \
22300 _(set, "usage: set <variable-name> <value>")                    \
22301 _(script, "usage: script <file-name>")                          \
22302 _(statseg, "usage: statseg")                                    \
22303 _(unset, "usage: unset <variable-name>")
22304
22305 #define _(N,n)                                  \
22306     static void vl_api_##n##_t_handler_uni      \
22307     (vl_api_##n##_t * mp)                       \
22308     {                                           \
22309         vat_main_t * vam = &vat_main;           \
22310         if (vam->json_output) {                 \
22311             vl_api_##n##_t_handler_json(mp);    \
22312         } else {                                \
22313             vl_api_##n##_t_handler(mp);         \
22314         }                                       \
22315     }
22316 foreach_vpe_api_reply_msg;
22317 #if VPP_API_TEST_BUILTIN == 0
22318 foreach_standalone_reply_msg;
22319 #endif
22320 #undef _
22321
22322 void
22323 vat_api_hookup (vat_main_t * vam)
22324 {
22325 #define _(N,n)                                                  \
22326     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22327                            vl_api_##n##_t_handler_uni,          \
22328                            vl_noop_handler,                     \
22329                            vl_api_##n##_t_endian,               \
22330                            vl_api_##n##_t_print,                \
22331                            sizeof(vl_api_##n##_t), 1);
22332   foreach_vpe_api_reply_msg;
22333 #if VPP_API_TEST_BUILTIN == 0
22334   foreach_standalone_reply_msg;
22335 #endif
22336 #undef _
22337
22338 #if (VPP_API_TEST_BUILTIN==0)
22339   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22340
22341   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22342
22343   vam->function_by_name = hash_create_string (0, sizeof (uword));
22344
22345   vam->help_by_name = hash_create_string (0, sizeof (uword));
22346 #endif
22347
22348   /* API messages we can send */
22349 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22350   foreach_vpe_api_msg;
22351 #undef _
22352
22353   /* Help strings */
22354 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22355   foreach_vpe_api_msg;
22356 #undef _
22357
22358   /* CLI functions */
22359 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22360   foreach_cli_function;
22361 #undef _
22362
22363   /* Help strings */
22364 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22365   foreach_cli_function;
22366 #undef _
22367 }
22368
22369 #if VPP_API_TEST_BUILTIN
22370 static clib_error_t *
22371 vat_api_hookup_shim (vlib_main_t * vm)
22372 {
22373   vat_api_hookup (&vat_main);
22374   return 0;
22375 }
22376
22377 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22378 #endif
22379
22380 /*
22381  * fd.io coding-style-patch-verification: ON
22382  *
22383  * Local Variables:
22384  * eval: (c-set-style "gnu")
22385  * End:
22386  */