ipsec: ipsec-tun protect
[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       vec_free (s);
1356
1357       errmsg ("build directory: %v\n", s);
1358     }
1359   vam->retval = retval;
1360   vam->result_ready = 1;
1361 }
1362
1363 static void vl_api_show_version_reply_t_handler_json
1364   (vl_api_show_version_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   char *p = (char *) &mp->program;
1372   vat_json_object_add_string_copy (&node, "program",
1373                                    vl_api_from_api_string ((vl_api_string_t *)
1374                                                            p));
1375   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1376   vat_json_object_add_string_copy (&node, "version",
1377                                    vl_api_from_api_string ((vl_api_string_t *)
1378                                                            p));
1379   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1380   vat_json_object_add_string_copy (&node, "build_date",
1381                                    vl_api_from_api_string ((vl_api_string_t *)
1382                                                            p));
1383   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1384   vat_json_object_add_string_copy (&node, "build_directory",
1385                                    vl_api_from_api_string ((vl_api_string_t *)
1386                                                            p));
1387
1388   vat_json_print (vam->ofp, &node);
1389   vat_json_free (&node);
1390
1391   vam->retval = ntohl (mp->retval);
1392   vam->result_ready = 1;
1393 }
1394
1395 static void vl_api_show_threads_reply_t_handler
1396   (vl_api_show_threads_reply_t * mp)
1397 {
1398   vat_main_t *vam = &vat_main;
1399   i32 retval = ntohl (mp->retval);
1400   int i, count = 0;
1401
1402   if (retval >= 0)
1403     count = ntohl (mp->count);
1404
1405   for (i = 0; i < count; i++)
1406     print (vam->ofp,
1407            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1408            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1409            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1410            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1411            ntohl (mp->thread_data[i].cpu_socket));
1412
1413   vam->retval = retval;
1414   vam->result_ready = 1;
1415 }
1416
1417 static void vl_api_show_threads_reply_t_handler_json
1418   (vl_api_show_threads_reply_t * mp)
1419 {
1420   vat_main_t *vam = &vat_main;
1421   vat_json_node_t node;
1422   vl_api_thread_data_t *td;
1423   i32 retval = ntohl (mp->retval);
1424   int i, count = 0;
1425
1426   if (retval >= 0)
1427     count = ntohl (mp->count);
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", retval);
1431   vat_json_object_add_uint (&node, "count", count);
1432
1433   for (i = 0; i < count; i++)
1434     {
1435       td = &mp->thread_data[i];
1436       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1437       vat_json_object_add_string_copy (&node, "name", td->name);
1438       vat_json_object_add_string_copy (&node, "type", td->type);
1439       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1440       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1441       vat_json_object_add_int (&node, "core", ntohl (td->id));
1442       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1443     }
1444
1445   vat_json_print (vam->ofp, &node);
1446   vat_json_free (&node);
1447
1448   vam->retval = retval;
1449   vam->result_ready = 1;
1450 }
1451
1452 static int
1453 api_show_threads (vat_main_t * vam)
1454 {
1455   vl_api_show_threads_t *mp;
1456   int ret;
1457
1458   print (vam->ofp,
1459          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1460          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1461
1462   M (SHOW_THREADS, mp);
1463
1464   S (mp);
1465   W (ret);
1466   return ret;
1467 }
1468
1469 static void
1470 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1471 {
1472   u32 sw_if_index = ntohl (mp->sw_if_index);
1473   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1474           mp->mac_ip ? "mac/ip binding" : "address resolution",
1475           ntohl (mp->pid), format_ip4_address, mp->ip,
1476           format_vl_api_mac_address, &mp->mac, sw_if_index);
1477 }
1478
1479 static void
1480 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1481 {
1482   /* JSON output not supported */
1483 }
1484
1485 static void
1486 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1487 {
1488   u32 sw_if_index = ntohl (mp->sw_if_index);
1489   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1490           mp->mac_ip ? "mac/ip binding" : "address resolution",
1491           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1492           format_vl_api_mac_address, mp->mac, sw_if_index);
1493 }
1494
1495 static void
1496 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1497 {
1498   /* JSON output not supported */
1499 }
1500
1501 static void
1502 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1503 {
1504   u32 n_macs = ntohl (mp->n_macs);
1505   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1506           ntohl (mp->pid), mp->client_index, n_macs);
1507   int i;
1508   for (i = 0; i < n_macs; i++)
1509     {
1510       vl_api_mac_entry_t *mac = &mp->mac[i];
1511       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1512               i + 1, ntohl (mac->sw_if_index),
1513               format_ethernet_address, mac->mac_addr, mac->action);
1514       if (i == 1000)
1515         break;
1516     }
1517 }
1518
1519 static void
1520 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1521 {
1522   /* JSON output not supported */
1523 }
1524
1525 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1526 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1527
1528 /*
1529  * Special-case: build the bridge domain table, maintain
1530  * the next bd id vbl.
1531  */
1532 static void vl_api_bridge_domain_details_t_handler
1533   (vl_api_bridge_domain_details_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1537   int i;
1538
1539   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1540          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1541
1542   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1543          ntohl (mp->bd_id), mp->learn, mp->forward,
1544          mp->flood, ntohl (mp->bvi_sw_if_index),
1545          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1546
1547   if (n_sw_ifs)
1548     {
1549       vl_api_bridge_domain_sw_if_t *sw_ifs;
1550       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1551              "Interface Name");
1552
1553       sw_ifs = mp->sw_if_details;
1554       for (i = 0; i < n_sw_ifs; i++)
1555         {
1556           u8 *sw_if_name = 0;
1557           u32 sw_if_index;
1558           hash_pair_t *p;
1559
1560           sw_if_index = ntohl (sw_ifs->sw_if_index);
1561
1562           /* *INDENT-OFF* */
1563           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1564                              ({
1565                                if ((u32) p->value[0] == sw_if_index)
1566                                  {
1567                                    sw_if_name = (u8 *)(p->key);
1568                                    break;
1569                                  }
1570                              }));
1571           /* *INDENT-ON* */
1572           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1573                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1574                  "sw_if_index not found!");
1575
1576           sw_ifs++;
1577         }
1578     }
1579 }
1580
1581 static void vl_api_bridge_domain_details_t_handler_json
1582   (vl_api_bridge_domain_details_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   vat_json_node_t *node, *array = NULL;
1586   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1587
1588   if (VAT_JSON_ARRAY != vam->json_tree.type)
1589     {
1590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1591       vat_json_init_array (&vam->json_tree);
1592     }
1593   node = vat_json_array_add (&vam->json_tree);
1594
1595   vat_json_init_object (node);
1596   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1597   vat_json_object_add_uint (node, "flood", mp->flood);
1598   vat_json_object_add_uint (node, "forward", mp->forward);
1599   vat_json_object_add_uint (node, "learn", mp->learn);
1600   vat_json_object_add_uint (node, "bvi_sw_if_index",
1601                             ntohl (mp->bvi_sw_if_index));
1602   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1603   array = vat_json_object_add (node, "sw_if");
1604   vat_json_init_array (array);
1605
1606
1607
1608   if (n_sw_ifs)
1609     {
1610       vl_api_bridge_domain_sw_if_t *sw_ifs;
1611       int i;
1612
1613       sw_ifs = mp->sw_if_details;
1614       for (i = 0; i < n_sw_ifs; i++)
1615         {
1616           node = vat_json_array_add (array);
1617           vat_json_init_object (node);
1618           vat_json_object_add_uint (node, "sw_if_index",
1619                                     ntohl (sw_ifs->sw_if_index));
1620           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1621           sw_ifs++;
1622         }
1623     }
1624 }
1625
1626 static void vl_api_control_ping_reply_t_handler
1627   (vl_api_control_ping_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->result_ready = 1;
1639     }
1640   if (vam->socket_client_main)
1641     vam->socket_client_main->control_pings_outstanding--;
1642 }
1643
1644 static void vl_api_control_ping_reply_t_handler_json
1645   (vl_api_control_ping_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649
1650   if (VAT_JSON_NONE != vam->json_tree.type)
1651     {
1652       vat_json_print (vam->ofp, &vam->json_tree);
1653       vat_json_free (&vam->json_tree);
1654       vam->json_tree.type = VAT_JSON_NONE;
1655     }
1656   else
1657     {
1658       /* just print [] */
1659       vat_json_init_array (&vam->json_tree);
1660       vat_json_print (vam->ofp, &vam->json_tree);
1661       vam->json_tree.type = VAT_JSON_NONE;
1662     }
1663
1664   vam->retval = retval;
1665   vam->result_ready = 1;
1666 }
1667
1668 static void
1669   vl_api_bridge_domain_set_mac_age_reply_t_handler
1670   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1686   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693
1694   vat_json_print (vam->ofp, &node);
1695   vat_json_free (&node);
1696
1697   vam->retval = ntohl (mp->retval);
1698   vam->result_ready = 1;
1699 }
1700
1701 static void
1702 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1703 {
1704   vat_main_t *vam = &vat_main;
1705   i32 retval = ntohl (mp->retval);
1706   if (vam->async_mode)
1707     {
1708       vam->async_errors += (retval < 0);
1709     }
1710   else
1711     {
1712       vam->retval = retval;
1713       vam->result_ready = 1;
1714     }
1715 }
1716
1717 static void vl_api_l2_flags_reply_t_handler_json
1718   (vl_api_l2_flags_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1726                             ntohl (mp->resulting_feature_bitmap));
1727
1728   vat_json_print (vam->ofp, &node);
1729   vat_json_free (&node);
1730
1731   vam->retval = ntohl (mp->retval);
1732   vam->result_ready = 1;
1733 }
1734
1735 static void vl_api_bridge_flags_reply_t_handler
1736   (vl_api_bridge_flags_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_bridge_flags_reply_t_handler_json
1752   (vl_api_bridge_flags_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1760                             ntohl (mp->resulting_feature_bitmap));
1761
1762   vat_json_print (vam->ofp, &node);
1763   vat_json_free (&node);
1764
1765   vam->retval = ntohl (mp->retval);
1766   vam->result_ready = 1;
1767 }
1768
1769 static void
1770 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   i32 retval = ntohl (mp->retval);
1774   if (vam->async_mode)
1775     {
1776       vam->async_errors += (retval < 0);
1777     }
1778   else
1779     {
1780       vam->retval = retval;
1781       vam->sw_if_index = ntohl (mp->sw_if_index);
1782       vam->result_ready = 1;
1783     }
1784
1785 }
1786
1787 static void vl_api_tap_create_v2_reply_t_handler_json
1788   (vl_api_tap_create_v2_reply_t * mp)
1789 {
1790   vat_main_t *vam = &vat_main;
1791   vat_json_node_t node;
1792
1793   vat_json_init_object (&node);
1794   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1795   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1796
1797   vat_json_print (vam->ofp, &node);
1798   vat_json_free (&node);
1799
1800   vam->retval = ntohl (mp->retval);
1801   vam->result_ready = 1;
1802
1803 }
1804
1805 static void
1806 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   i32 retval = ntohl (mp->retval);
1810   if (vam->async_mode)
1811     {
1812       vam->async_errors += (retval < 0);
1813     }
1814   else
1815     {
1816       vam->retval = retval;
1817       vam->result_ready = 1;
1818     }
1819 }
1820
1821 static void vl_api_tap_delete_v2_reply_t_handler_json
1822   (vl_api_tap_delete_v2_reply_t * mp)
1823 {
1824   vat_main_t *vam = &vat_main;
1825   vat_json_node_t node;
1826
1827   vat_json_init_object (&node);
1828   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1829
1830   vat_json_print (vam->ofp, &node);
1831   vat_json_free (&node);
1832
1833   vam->retval = ntohl (mp->retval);
1834   vam->result_ready = 1;
1835 }
1836
1837 static void
1838 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1839                                           mp)
1840 {
1841   vat_main_t *vam = &vat_main;
1842   i32 retval = ntohl (mp->retval);
1843   if (vam->async_mode)
1844     {
1845       vam->async_errors += (retval < 0);
1846     }
1847   else
1848     {
1849       vam->retval = retval;
1850       vam->sw_if_index = ntohl (mp->sw_if_index);
1851       vam->result_ready = 1;
1852     }
1853 }
1854
1855 static void vl_api_virtio_pci_create_reply_t_handler_json
1856   (vl_api_virtio_pci_create_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   vat_json_node_t node;
1860
1861   vat_json_init_object (&node);
1862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1863   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1864
1865   vat_json_print (vam->ofp, &node);
1866   vat_json_free (&node);
1867
1868   vam->retval = ntohl (mp->retval);
1869   vam->result_ready = 1;
1870
1871 }
1872
1873 static void
1874 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1875                                           mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   i32 retval = ntohl (mp->retval);
1879   if (vam->async_mode)
1880     {
1881       vam->async_errors += (retval < 0);
1882     }
1883   else
1884     {
1885       vam->retval = retval;
1886       vam->result_ready = 1;
1887     }
1888 }
1889
1890 static void vl_api_virtio_pci_delete_reply_t_handler_json
1891   (vl_api_virtio_pci_delete_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   vat_json_node_t node;
1895
1896   vat_json_init_object (&node);
1897   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1898
1899   vat_json_print (vam->ofp, &node);
1900   vat_json_free (&node);
1901
1902   vam->retval = ntohl (mp->retval);
1903   vam->result_ready = 1;
1904 }
1905
1906 static void
1907 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   i32 retval = ntohl (mp->retval);
1911
1912   if (vam->async_mode)
1913     {
1914       vam->async_errors += (retval < 0);
1915     }
1916   else
1917     {
1918       vam->retval = retval;
1919       vam->sw_if_index = ntohl (mp->sw_if_index);
1920       vam->result_ready = 1;
1921     }
1922 }
1923
1924 static void vl_api_bond_create_reply_t_handler_json
1925   (vl_api_bond_create_reply_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   vat_json_node_t node;
1929
1930   vat_json_init_object (&node);
1931   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1932   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1933
1934   vat_json_print (vam->ofp, &node);
1935   vat_json_free (&node);
1936
1937   vam->retval = ntohl (mp->retval);
1938   vam->result_ready = 1;
1939 }
1940
1941 static void
1942 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   i32 retval = ntohl (mp->retval);
1946
1947   if (vam->async_mode)
1948     {
1949       vam->async_errors += (retval < 0);
1950     }
1951   else
1952     {
1953       vam->retval = retval;
1954       vam->result_ready = 1;
1955     }
1956 }
1957
1958 static void vl_api_bond_delete_reply_t_handler_json
1959   (vl_api_bond_delete_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   vat_json_node_t node;
1963
1964   vat_json_init_object (&node);
1965   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1966
1967   vat_json_print (vam->ofp, &node);
1968   vat_json_free (&node);
1969
1970   vam->retval = ntohl (mp->retval);
1971   vam->result_ready = 1;
1972 }
1973
1974 static void
1975 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   i32 retval = ntohl (mp->retval);
1979
1980   if (vam->async_mode)
1981     {
1982       vam->async_errors += (retval < 0);
1983     }
1984   else
1985     {
1986       vam->retval = retval;
1987       vam->result_ready = 1;
1988     }
1989 }
1990
1991 static void vl_api_bond_enslave_reply_t_handler_json
1992   (vl_api_bond_enslave_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   vat_json_node_t node;
1996
1997   vat_json_init_object (&node);
1998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1999
2000   vat_json_print (vam->ofp, &node);
2001   vat_json_free (&node);
2002
2003   vam->retval = ntohl (mp->retval);
2004   vam->result_ready = 1;
2005 }
2006
2007 static void
2008 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2009                                           mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   i32 retval = ntohl (mp->retval);
2013
2014   if (vam->async_mode)
2015     {
2016       vam->async_errors += (retval < 0);
2017     }
2018   else
2019     {
2020       vam->retval = retval;
2021       vam->result_ready = 1;
2022     }
2023 }
2024
2025 static void vl_api_bond_detach_slave_reply_t_handler_json
2026   (vl_api_bond_detach_slave_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vat_json_node_t node;
2030
2031   vat_json_init_object (&node);
2032   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2033
2034   vat_json_print (vam->ofp, &node);
2035   vat_json_free (&node);
2036
2037   vam->retval = ntohl (mp->retval);
2038   vam->result_ready = 1;
2039 }
2040
2041 static void vl_api_sw_interface_bond_details_t_handler
2042   (vl_api_sw_interface_bond_details_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045
2046   print (vam->ofp,
2047          "%-16s %-12d %-12U %-13U %-14u %-14u",
2048          mp->interface_name, ntohl (mp->sw_if_index),
2049          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2050          ntohl (mp->active_slaves), ntohl (mp->slaves));
2051 }
2052
2053 static void vl_api_sw_interface_bond_details_t_handler_json
2054   (vl_api_sw_interface_bond_details_t * mp)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   vat_json_node_t *node = NULL;
2058
2059   if (VAT_JSON_ARRAY != vam->json_tree.type)
2060     {
2061       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2062       vat_json_init_array (&vam->json_tree);
2063     }
2064   node = vat_json_array_add (&vam->json_tree);
2065
2066   vat_json_init_object (node);
2067   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2068   vat_json_object_add_string_copy (node, "interface_name",
2069                                    mp->interface_name);
2070   vat_json_object_add_uint (node, "mode", mp->mode);
2071   vat_json_object_add_uint (node, "load_balance", mp->lb);
2072   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2073   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2074 }
2075
2076 static int
2077 api_sw_interface_bond_dump (vat_main_t * vam)
2078 {
2079   vl_api_sw_interface_bond_dump_t *mp;
2080   vl_api_control_ping_t *mp_ping;
2081   int ret;
2082
2083   print (vam->ofp,
2084          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2085          "interface name", "sw_if_index", "mode", "load balance",
2086          "active slaves", "slaves");
2087
2088   /* Get list of bond interfaces */
2089   M (SW_INTERFACE_BOND_DUMP, mp);
2090   S (mp);
2091
2092   /* Use a control ping for synchronization */
2093   MPING (CONTROL_PING, mp_ping);
2094   S (mp_ping);
2095
2096   W (ret);
2097   return ret;
2098 }
2099
2100 static void vl_api_sw_interface_slave_details_t_handler
2101   (vl_api_sw_interface_slave_details_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104
2105   print (vam->ofp,
2106          "%-25s %-12d %-12d %d", mp->interface_name,
2107          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2108 }
2109
2110 static void vl_api_sw_interface_slave_details_t_handler_json
2111   (vl_api_sw_interface_slave_details_t * mp)
2112 {
2113   vat_main_t *vam = &vat_main;
2114   vat_json_node_t *node = NULL;
2115
2116   if (VAT_JSON_ARRAY != vam->json_tree.type)
2117     {
2118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2119       vat_json_init_array (&vam->json_tree);
2120     }
2121   node = vat_json_array_add (&vam->json_tree);
2122
2123   vat_json_init_object (node);
2124   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2125   vat_json_object_add_string_copy (node, "interface_name",
2126                                    mp->interface_name);
2127   vat_json_object_add_uint (node, "passive", mp->is_passive);
2128   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2129 }
2130
2131 static int
2132 api_sw_interface_slave_dump (vat_main_t * vam)
2133 {
2134   unformat_input_t *i = vam->input;
2135   vl_api_sw_interface_slave_dump_t *mp;
2136   vl_api_control_ping_t *mp_ping;
2137   u32 sw_if_index = ~0;
2138   u8 sw_if_index_set = 0;
2139   int ret;
2140
2141   /* Parse args required to build the message */
2142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2143     {
2144       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2145         sw_if_index_set = 1;
2146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2147         sw_if_index_set = 1;
2148       else
2149         break;
2150     }
2151
2152   if (sw_if_index_set == 0)
2153     {
2154       errmsg ("missing vpp interface name. ");
2155       return -99;
2156     }
2157
2158   print (vam->ofp,
2159          "\n%-25s %-12s %-12s %s",
2160          "slave interface name", "sw_if_index", "passive", "long_timeout");
2161
2162   /* Get list of bond interfaces */
2163   M (SW_INTERFACE_SLAVE_DUMP, mp);
2164   mp->sw_if_index = ntohl (sw_if_index);
2165   S (mp);
2166
2167   /* Use a control ping for synchronization */
2168   MPING (CONTROL_PING, mp_ping);
2169   S (mp_ping);
2170
2171   W (ret);
2172   return ret;
2173 }
2174
2175 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2176   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2177 {
2178   vat_main_t *vam = &vat_main;
2179   i32 retval = ntohl (mp->retval);
2180   if (vam->async_mode)
2181     {
2182       vam->async_errors += (retval < 0);
2183     }
2184   else
2185     {
2186       vam->retval = retval;
2187       vam->sw_if_index = ntohl (mp->sw_if_index);
2188       vam->result_ready = 1;
2189     }
2190   vam->regenerate_interface_table = 1;
2191 }
2192
2193 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2194   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2195 {
2196   vat_main_t *vam = &vat_main;
2197   vat_json_node_t node;
2198
2199   vat_json_init_object (&node);
2200   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2201   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2202                             ntohl (mp->sw_if_index));
2203
2204   vat_json_print (vam->ofp, &node);
2205   vat_json_free (&node);
2206
2207   vam->retval = ntohl (mp->retval);
2208   vam->result_ready = 1;
2209 }
2210
2211 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2212   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2213 {
2214   vat_main_t *vam = &vat_main;
2215   i32 retval = ntohl (mp->retval);
2216   if (vam->async_mode)
2217     {
2218       vam->async_errors += (retval < 0);
2219     }
2220   else
2221     {
2222       vam->retval = retval;
2223       vam->sw_if_index = ntohl (mp->sw_if_index);
2224       vam->result_ready = 1;
2225     }
2226 }
2227
2228 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2229   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2230 {
2231   vat_main_t *vam = &vat_main;
2232   vat_json_node_t node;
2233
2234   vat_json_init_object (&node);
2235   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2236   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2237
2238   vat_json_print (vam->ofp, &node);
2239   vat_json_free (&node);
2240
2241   vam->retval = ntohl (mp->retval);
2242   vam->result_ready = 1;
2243 }
2244
2245 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2246   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   i32 retval = ntohl (mp->retval);
2250   if (vam->async_mode)
2251     {
2252       vam->async_errors += (retval < 0);
2253     }
2254   else
2255     {
2256       vam->retval = retval;
2257       vam->result_ready = 1;
2258     }
2259 }
2260
2261 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2262   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t node;
2266
2267   vat_json_init_object (&node);
2268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269   vat_json_object_add_uint (&node, "fwd_entry_index",
2270                             clib_net_to_host_u32 (mp->fwd_entry_index));
2271
2272   vat_json_print (vam->ofp, &node);
2273   vat_json_free (&node);
2274
2275   vam->retval = ntohl (mp->retval);
2276   vam->result_ready = 1;
2277 }
2278
2279 u8 *
2280 format_lisp_transport_protocol (u8 * s, va_list * args)
2281 {
2282   u32 proto = va_arg (*args, u32);
2283
2284   switch (proto)
2285     {
2286     case 1:
2287       return format (s, "udp");
2288     case 2:
2289       return format (s, "api");
2290     default:
2291       return 0;
2292     }
2293   return 0;
2294 }
2295
2296 static void vl_api_one_get_transport_protocol_reply_t_handler
2297   (vl_api_one_get_transport_protocol_reply_t * mp)
2298 {
2299   vat_main_t *vam = &vat_main;
2300   i32 retval = ntohl (mp->retval);
2301   if (vam->async_mode)
2302     {
2303       vam->async_errors += (retval < 0);
2304     }
2305   else
2306     {
2307       u32 proto = mp->protocol;
2308       print (vam->ofp, "Transport protocol: %U",
2309              format_lisp_transport_protocol, proto);
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312     }
2313 }
2314
2315 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2316   (vl_api_one_get_transport_protocol_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   vat_json_node_t node;
2320   u8 *s;
2321
2322   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2323   vec_add1 (s, 0);
2324
2325   vat_json_init_object (&node);
2326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2327   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2328
2329   vec_free (s);
2330   vat_json_print (vam->ofp, &node);
2331   vat_json_free (&node);
2332
2333   vam->retval = ntohl (mp->retval);
2334   vam->result_ready = 1;
2335 }
2336
2337 static void vl_api_one_add_del_locator_set_reply_t_handler
2338   (vl_api_one_add_del_locator_set_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   i32 retval = ntohl (mp->retval);
2342   if (vam->async_mode)
2343     {
2344       vam->async_errors += (retval < 0);
2345     }
2346   else
2347     {
2348       vam->retval = retval;
2349       vam->result_ready = 1;
2350     }
2351 }
2352
2353 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2354   (vl_api_one_add_del_locator_set_reply_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   vat_json_node_t node;
2358
2359   vat_json_init_object (&node);
2360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2361   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2362
2363   vat_json_print (vam->ofp, &node);
2364   vat_json_free (&node);
2365
2366   vam->retval = ntohl (mp->retval);
2367   vam->result_ready = 1;
2368 }
2369
2370 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2371   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2372 {
2373   vat_main_t *vam = &vat_main;
2374   i32 retval = ntohl (mp->retval);
2375   if (vam->async_mode)
2376     {
2377       vam->async_errors += (retval < 0);
2378     }
2379   else
2380     {
2381       vam->retval = retval;
2382       vam->sw_if_index = ntohl (mp->sw_if_index);
2383       vam->result_ready = 1;
2384     }
2385   vam->regenerate_interface_table = 1;
2386 }
2387
2388 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2389   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2390 {
2391   vat_main_t *vam = &vat_main;
2392   vat_json_node_t node;
2393
2394   vat_json_init_object (&node);
2395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2397
2398   vat_json_print (vam->ofp, &node);
2399   vat_json_free (&node);
2400
2401   vam->retval = ntohl (mp->retval);
2402   vam->result_ready = 1;
2403 }
2404
2405 static void vl_api_vxlan_offload_rx_reply_t_handler
2406   (vl_api_vxlan_offload_rx_reply_t * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   i32 retval = ntohl (mp->retval);
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->result_ready = 1;
2418     }
2419 }
2420
2421 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2422   (vl_api_vxlan_offload_rx_reply_t * mp)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   vat_json_node_t node;
2426
2427   vat_json_init_object (&node);
2428   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2429
2430   vat_json_print (vam->ofp, &node);
2431   vat_json_free (&node);
2432
2433   vam->retval = ntohl (mp->retval);
2434   vam->result_ready = 1;
2435 }
2436
2437 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2438   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2439 {
2440   vat_main_t *vam = &vat_main;
2441   i32 retval = ntohl (mp->retval);
2442   if (vam->async_mode)
2443     {
2444       vam->async_errors += (retval < 0);
2445     }
2446   else
2447     {
2448       vam->retval = retval;
2449       vam->sw_if_index = ntohl (mp->sw_if_index);
2450       vam->result_ready = 1;
2451     }
2452 }
2453
2454 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2455   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   vat_json_node_t node;
2459
2460   vat_json_init_object (&node);
2461   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2462   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2463
2464   vat_json_print (vam->ofp, &node);
2465   vat_json_free (&node);
2466
2467   vam->retval = ntohl (mp->retval);
2468   vam->result_ready = 1;
2469 }
2470
2471 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2472   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2473 {
2474   vat_main_t *vam = &vat_main;
2475   i32 retval = ntohl (mp->retval);
2476   if (vam->async_mode)
2477     {
2478       vam->async_errors += (retval < 0);
2479     }
2480   else
2481     {
2482       vam->retval = retval;
2483       vam->sw_if_index = ntohl (mp->sw_if_index);
2484       vam->result_ready = 1;
2485     }
2486   vam->regenerate_interface_table = 1;
2487 }
2488
2489 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2490   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2491 {
2492   vat_main_t *vam = &vat_main;
2493   vat_json_node_t node;
2494
2495   vat_json_init_object (&node);
2496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2497   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2498
2499   vat_json_print (vam->ofp, &node);
2500   vat_json_free (&node);
2501
2502   vam->retval = ntohl (mp->retval);
2503   vam->result_ready = 1;
2504 }
2505
2506 static void vl_api_gre_tunnel_add_del_reply_t_handler
2507   (vl_api_gre_tunnel_add_del_reply_t * mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   i32 retval = ntohl (mp->retval);
2511   if (vam->async_mode)
2512     {
2513       vam->async_errors += (retval < 0);
2514     }
2515   else
2516     {
2517       vam->retval = retval;
2518       vam->sw_if_index = ntohl (mp->sw_if_index);
2519       vam->result_ready = 1;
2520     }
2521 }
2522
2523 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2524   (vl_api_gre_tunnel_add_del_reply_t * mp)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   vat_json_node_t node;
2528
2529   vat_json_init_object (&node);
2530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2532
2533   vat_json_print (vam->ofp, &node);
2534   vat_json_free (&node);
2535
2536   vam->retval = ntohl (mp->retval);
2537   vam->result_ready = 1;
2538 }
2539
2540 static void vl_api_create_vhost_user_if_reply_t_handler
2541   (vl_api_create_vhost_user_if_reply_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   i32 retval = ntohl (mp->retval);
2545   if (vam->async_mode)
2546     {
2547       vam->async_errors += (retval < 0);
2548     }
2549   else
2550     {
2551       vam->retval = retval;
2552       vam->sw_if_index = ntohl (mp->sw_if_index);
2553       vam->result_ready = 1;
2554     }
2555   vam->regenerate_interface_table = 1;
2556 }
2557
2558 static void vl_api_create_vhost_user_if_reply_t_handler_json
2559   (vl_api_create_vhost_user_if_reply_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vat_json_node_t node;
2563
2564   vat_json_init_object (&node);
2565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2566   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2567
2568   vat_json_print (vam->ofp, &node);
2569   vat_json_free (&node);
2570
2571   vam->retval = ntohl (mp->retval);
2572   vam->result_ready = 1;
2573 }
2574
2575 static void vl_api_dns_resolve_name_reply_t_handler
2576   (vl_api_dns_resolve_name_reply_t * mp)
2577 {
2578   vat_main_t *vam = &vat_main;
2579   i32 retval = ntohl (mp->retval);
2580   if (vam->async_mode)
2581     {
2582       vam->async_errors += (retval < 0);
2583     }
2584   else
2585     {
2586       vam->retval = retval;
2587       vam->result_ready = 1;
2588
2589       if (retval == 0)
2590         {
2591           if (mp->ip4_set)
2592             clib_warning ("ip4 address %U", format_ip4_address,
2593                           (ip4_address_t *) mp->ip4_address);
2594           if (mp->ip6_set)
2595             clib_warning ("ip6 address %U", format_ip6_address,
2596                           (ip6_address_t *) mp->ip6_address);
2597         }
2598       else
2599         clib_warning ("retval %d", retval);
2600     }
2601 }
2602
2603 static void vl_api_dns_resolve_name_reply_t_handler_json
2604   (vl_api_dns_resolve_name_reply_t * mp)
2605 {
2606   clib_warning ("not implemented");
2607 }
2608
2609 static void vl_api_dns_resolve_ip_reply_t_handler
2610   (vl_api_dns_resolve_ip_reply_t * mp)
2611 {
2612   vat_main_t *vam = &vat_main;
2613   i32 retval = ntohl (mp->retval);
2614   if (vam->async_mode)
2615     {
2616       vam->async_errors += (retval < 0);
2617     }
2618   else
2619     {
2620       vam->retval = retval;
2621       vam->result_ready = 1;
2622
2623       if (retval == 0)
2624         {
2625           clib_warning ("canonical name %s", mp->name);
2626         }
2627       else
2628         clib_warning ("retval %d", retval);
2629     }
2630 }
2631
2632 static void vl_api_dns_resolve_ip_reply_t_handler_json
2633   (vl_api_dns_resolve_ip_reply_t * mp)
2634 {
2635   clib_warning ("not implemented");
2636 }
2637
2638
2639 static void vl_api_ip_address_details_t_handler
2640   (vl_api_ip_address_details_t * mp)
2641 {
2642   vat_main_t *vam = &vat_main;
2643   static ip_address_details_t empty_ip_address_details = { {0} };
2644   ip_address_details_t *address = NULL;
2645   ip_details_t *current_ip_details = NULL;
2646   ip_details_t *details = NULL;
2647
2648   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2649
2650   if (!details || vam->current_sw_if_index >= vec_len (details)
2651       || !details[vam->current_sw_if_index].present)
2652     {
2653       errmsg ("ip address details arrived but not stored");
2654       errmsg ("ip_dump should be called first");
2655       return;
2656     }
2657
2658   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2659
2660 #define addresses (current_ip_details->addr)
2661
2662   vec_validate_init_empty (addresses, vec_len (addresses),
2663                            empty_ip_address_details);
2664
2665   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2666
2667   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2668   address->prefix_length = mp->prefix.address_length;
2669 #undef addresses
2670 }
2671
2672 static void vl_api_ip_address_details_t_handler_json
2673   (vl_api_ip_address_details_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   vat_json_node_t *node = NULL;
2677
2678   if (VAT_JSON_ARRAY != vam->json_tree.type)
2679     {
2680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2681       vat_json_init_array (&vam->json_tree);
2682     }
2683   node = vat_json_array_add (&vam->json_tree);
2684
2685   vat_json_init_object (node);
2686   vat_json_object_add_prefix (node, &mp->prefix);
2687 }
2688
2689 static void
2690 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   static ip_details_t empty_ip_details = { 0 };
2694   ip_details_t *ip = NULL;
2695   u32 sw_if_index = ~0;
2696
2697   sw_if_index = ntohl (mp->sw_if_index);
2698
2699   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2700                            sw_if_index, empty_ip_details);
2701
2702   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2703                          sw_if_index);
2704
2705   ip->present = 1;
2706 }
2707
2708 static void
2709 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   vat_json_array_add_uint (&vam->json_tree,
2719                            clib_net_to_host_u32 (mp->sw_if_index));
2720 }
2721
2722 static void
2723 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2724 {
2725   u8 *s, i;
2726
2727   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2728               "host_mac %U router_addr %U",
2729               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2730               mp->lease.hostname,
2731               format_ip4_address, mp->lease.host_address,
2732               format_ethernet_address, mp->lease.host_mac,
2733               format_ip4_address, mp->lease.router_address);
2734
2735   for (i = 0; i < mp->lease.count; i++)
2736     s =
2737       format (s, " domain_server_addr %U", format_ip4_address,
2738               mp->lease.domain_server[i].address);
2739
2740   errmsg ((char *) s);
2741   vec_free (s);
2742 }
2743
2744 static void vl_api_dhcp_compl_event_t_handler_json
2745   (vl_api_dhcp_compl_event_t * mp)
2746 {
2747   /* JSON output not supported */
2748 }
2749
2750 static void vl_api_get_first_msg_id_reply_t_handler
2751   (vl_api_get_first_msg_id_reply_t * mp)
2752 {
2753   vat_main_t *vam = &vat_main;
2754   i32 retval = ntohl (mp->retval);
2755
2756   if (vam->async_mode)
2757     {
2758       vam->async_errors += (retval < 0);
2759     }
2760   else
2761     {
2762       vam->retval = retval;
2763       vam->result_ready = 1;
2764     }
2765   if (retval >= 0)
2766     {
2767       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2768     }
2769 }
2770
2771 static void vl_api_get_first_msg_id_reply_t_handler_json
2772   (vl_api_get_first_msg_id_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   vat_json_node_t node;
2776
2777   vat_json_init_object (&node);
2778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2779   vat_json_object_add_uint (&node, "first_msg_id",
2780                             (uint) ntohs (mp->first_msg_id));
2781
2782   vat_json_print (vam->ofp, &node);
2783   vat_json_free (&node);
2784
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void vl_api_get_node_graph_reply_t_handler
2790   (vl_api_get_node_graph_reply_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793   api_main_t *am = &api_main;
2794   i32 retval = ntohl (mp->retval);
2795   u8 *pvt_copy, *reply;
2796   void *oldheap;
2797   vlib_node_t *node;
2798   int i;
2799
2800   if (vam->async_mode)
2801     {
2802       vam->async_errors += (retval < 0);
2803     }
2804   else
2805     {
2806       vam->retval = retval;
2807       vam->result_ready = 1;
2808     }
2809
2810   /* "Should never happen..." */
2811   if (retval != 0)
2812     return;
2813
2814   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2815   pvt_copy = vec_dup (reply);
2816
2817   /* Toss the shared-memory original... */
2818   pthread_mutex_lock (&am->vlib_rp->mutex);
2819   oldheap = svm_push_data_heap (am->vlib_rp);
2820
2821   vec_free (reply);
2822
2823   svm_pop_heap (oldheap);
2824   pthread_mutex_unlock (&am->vlib_rp->mutex);
2825
2826   if (vam->graph_nodes)
2827     {
2828       hash_free (vam->graph_node_index_by_name);
2829
2830       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2831         {
2832           node = vam->graph_nodes[0][i];
2833           vec_free (node->name);
2834           vec_free (node->next_nodes);
2835           vec_free (node);
2836         }
2837       vec_free (vam->graph_nodes[0]);
2838       vec_free (vam->graph_nodes);
2839     }
2840
2841   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2842   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2843   vec_free (pvt_copy);
2844
2845   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2846     {
2847       node = vam->graph_nodes[0][i];
2848       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2849     }
2850 }
2851
2852 static void vl_api_get_node_graph_reply_t_handler_json
2853   (vl_api_get_node_graph_reply_t * mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   api_main_t *am = &api_main;
2857   void *oldheap;
2858   vat_json_node_t node;
2859   u8 *reply;
2860
2861   /* $$$$ make this real? */
2862   vat_json_init_object (&node);
2863   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2864   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2865
2866   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   vat_json_print (vam->ofp, &node);
2878   vat_json_free (&node);
2879
2880   vam->retval = ntohl (mp->retval);
2881   vam->result_ready = 1;
2882 }
2883
2884 static void
2885 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2886 {
2887   vat_main_t *vam = &vat_main;
2888   u8 *s = 0;
2889
2890   if (mp->local)
2891     {
2892       s = format (s, "%=16d%=16d%=16d",
2893                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2894     }
2895   else
2896     {
2897       s = format (s, "%=16U%=16d%=16d",
2898                   mp->is_ipv6 ? format_ip6_address :
2899                   format_ip4_address,
2900                   mp->ip_address, mp->priority, mp->weight);
2901     }
2902
2903   print (vam->ofp, "%v", s);
2904   vec_free (s);
2905 }
2906
2907 static void
2908 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2909 {
2910   vat_main_t *vam = &vat_main;
2911   vat_json_node_t *node = NULL;
2912   struct in6_addr ip6;
2913   struct in_addr ip4;
2914
2915   if (VAT_JSON_ARRAY != vam->json_tree.type)
2916     {
2917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2918       vat_json_init_array (&vam->json_tree);
2919     }
2920   node = vat_json_array_add (&vam->json_tree);
2921   vat_json_init_object (node);
2922
2923   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2924   vat_json_object_add_uint (node, "priority", mp->priority);
2925   vat_json_object_add_uint (node, "weight", mp->weight);
2926
2927   if (mp->local)
2928     vat_json_object_add_uint (node, "sw_if_index",
2929                               clib_net_to_host_u32 (mp->sw_if_index));
2930   else
2931     {
2932       if (mp->is_ipv6)
2933         {
2934           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2935           vat_json_object_add_ip6 (node, "address", ip6);
2936         }
2937       else
2938         {
2939           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2940           vat_json_object_add_ip4 (node, "address", ip4);
2941         }
2942     }
2943 }
2944
2945 static void
2946 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2947                                           mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u8 *ls_name = 0;
2951
2952   ls_name = format (0, "%s", mp->ls_name);
2953
2954   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2955          ls_name);
2956   vec_free (ls_name);
2957 }
2958
2959 static void
2960   vl_api_one_locator_set_details_t_handler_json
2961   (vl_api_one_locator_set_details_t * mp)
2962 {
2963   vat_main_t *vam = &vat_main;
2964   vat_json_node_t *node = 0;
2965   u8 *ls_name = 0;
2966
2967   ls_name = format (0, "%s", mp->ls_name);
2968   vec_add1 (ls_name, 0);
2969
2970   if (VAT_JSON_ARRAY != vam->json_tree.type)
2971     {
2972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2973       vat_json_init_array (&vam->json_tree);
2974     }
2975   node = vat_json_array_add (&vam->json_tree);
2976
2977   vat_json_init_object (node);
2978   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2979   vat_json_object_add_uint (node, "ls_index",
2980                             clib_net_to_host_u32 (mp->ls_index));
2981   vec_free (ls_name);
2982 }
2983
2984 typedef struct
2985 {
2986   u32 spi;
2987   u8 si;
2988 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2989
2990 uword
2991 unformat_nsh_address (unformat_input_t * input, va_list * args)
2992 {
2993   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2994   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2995 }
2996
2997 u8 *
2998 format_nsh_address_vat (u8 * s, va_list * args)
2999 {
3000   nsh_t *a = va_arg (*args, nsh_t *);
3001   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3002 }
3003
3004 static u8 *
3005 format_lisp_flat_eid (u8 * s, va_list * args)
3006 {
3007   u32 type = va_arg (*args, u32);
3008   u8 *eid = va_arg (*args, u8 *);
3009   u32 eid_len = va_arg (*args, u32);
3010
3011   switch (type)
3012     {
3013     case 0:
3014       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3015     case 1:
3016       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3017     case 2:
3018       return format (s, "%U", format_ethernet_address, eid);
3019     case 3:
3020       return format (s, "%U", format_nsh_address_vat, eid);
3021     }
3022   return 0;
3023 }
3024
3025 static u8 *
3026 format_lisp_eid_vat (u8 * s, va_list * args)
3027 {
3028   u32 type = va_arg (*args, u32);
3029   u8 *eid = va_arg (*args, u8 *);
3030   u32 eid_len = va_arg (*args, u32);
3031   u8 *seid = va_arg (*args, u8 *);
3032   u32 seid_len = va_arg (*args, u32);
3033   u32 is_src_dst = va_arg (*args, u32);
3034
3035   if (is_src_dst)
3036     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3037
3038   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3039
3040   return s;
3041 }
3042
3043 static void
3044 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3045 {
3046   vat_main_t *vam = &vat_main;
3047   u8 *s = 0, *eid = 0;
3048
3049   if (~0 == mp->locator_set_index)
3050     s = format (0, "action: %d", mp->action);
3051   else
3052     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3053
3054   eid = format (0, "%U", format_lisp_eid_vat,
3055                 mp->eid_type,
3056                 mp->eid,
3057                 mp->eid_prefix_len,
3058                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3059   vec_add1 (eid, 0);
3060
3061   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3062          clib_net_to_host_u32 (mp->vni),
3063          eid,
3064          mp->is_local ? "local" : "remote",
3065          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3066          clib_net_to_host_u16 (mp->key_id), mp->key);
3067
3068   vec_free (s);
3069   vec_free (eid);
3070 }
3071
3072 static void
3073 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3074                                              * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   vat_json_node_t *node = 0;
3078   u8 *eid = 0;
3079
3080   if (VAT_JSON_ARRAY != vam->json_tree.type)
3081     {
3082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3083       vat_json_init_array (&vam->json_tree);
3084     }
3085   node = vat_json_array_add (&vam->json_tree);
3086
3087   vat_json_init_object (node);
3088   if (~0 == mp->locator_set_index)
3089     vat_json_object_add_uint (node, "action", mp->action);
3090   else
3091     vat_json_object_add_uint (node, "locator_set_index",
3092                               clib_net_to_host_u32 (mp->locator_set_index));
3093
3094   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3095   if (mp->eid_type == 3)
3096     {
3097       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3098       vat_json_init_object (nsh_json);
3099       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3100       vat_json_object_add_uint (nsh_json, "spi",
3101                                 clib_net_to_host_u32 (nsh->spi));
3102       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3103     }
3104   else
3105     {
3106       eid = format (0, "%U", format_lisp_eid_vat,
3107                     mp->eid_type,
3108                     mp->eid,
3109                     mp->eid_prefix_len,
3110                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3111       vec_add1 (eid, 0);
3112       vat_json_object_add_string_copy (node, "eid", eid);
3113       vec_free (eid);
3114     }
3115   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3116   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3117   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3118
3119   if (mp->key_id)
3120     {
3121       vat_json_object_add_uint (node, "key_id",
3122                                 clib_net_to_host_u16 (mp->key_id));
3123       vat_json_object_add_string_copy (node, "key", mp->key);
3124     }
3125 }
3126
3127 static void
3128 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   u8 *seid = 0, *deid = 0;
3132   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3133
3134   deid = format (0, "%U", format_lisp_eid_vat,
3135                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3136
3137   seid = format (0, "%U", format_lisp_eid_vat,
3138                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3139
3140   vec_add1 (deid, 0);
3141   vec_add1 (seid, 0);
3142
3143   if (mp->is_ip4)
3144     format_ip_address_fcn = format_ip4_address;
3145   else
3146     format_ip_address_fcn = format_ip6_address;
3147
3148
3149   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3150          clib_net_to_host_u32 (mp->vni),
3151          seid, deid,
3152          format_ip_address_fcn, mp->lloc,
3153          format_ip_address_fcn, mp->rloc,
3154          clib_net_to_host_u32 (mp->pkt_count),
3155          clib_net_to_host_u32 (mp->bytes));
3156
3157   vec_free (deid);
3158   vec_free (seid);
3159 }
3160
3161 static void
3162 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3163 {
3164   struct in6_addr ip6;
3165   struct in_addr ip4;
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t *node = 0;
3168   u8 *deid = 0, *seid = 0;
3169
3170   if (VAT_JSON_ARRAY != vam->json_tree.type)
3171     {
3172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3173       vat_json_init_array (&vam->json_tree);
3174     }
3175   node = vat_json_array_add (&vam->json_tree);
3176
3177   vat_json_init_object (node);
3178   deid = format (0, "%U", format_lisp_eid_vat,
3179                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3180
3181   seid = format (0, "%U", format_lisp_eid_vat,
3182                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3183
3184   vec_add1 (deid, 0);
3185   vec_add1 (seid, 0);
3186
3187   vat_json_object_add_string_copy (node, "seid", seid);
3188   vat_json_object_add_string_copy (node, "deid", deid);
3189   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3190
3191   if (mp->is_ip4)
3192     {
3193       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3194       vat_json_object_add_ip4 (node, "lloc", ip4);
3195       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3196       vat_json_object_add_ip4 (node, "rloc", ip4);
3197     }
3198   else
3199     {
3200       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3201       vat_json_object_add_ip6 (node, "lloc", ip6);
3202       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3203       vat_json_object_add_ip6 (node, "rloc", ip6);
3204     }
3205   vat_json_object_add_uint (node, "pkt_count",
3206                             clib_net_to_host_u32 (mp->pkt_count));
3207   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3208
3209   vec_free (deid);
3210   vec_free (seid);
3211 }
3212
3213 static void
3214   vl_api_one_eid_table_map_details_t_handler
3215   (vl_api_one_eid_table_map_details_t * mp)
3216 {
3217   vat_main_t *vam = &vat_main;
3218
3219   u8 *line = format (0, "%=10d%=10d",
3220                      clib_net_to_host_u32 (mp->vni),
3221                      clib_net_to_host_u32 (mp->dp_table));
3222   print (vam->ofp, "%v", line);
3223   vec_free (line);
3224 }
3225
3226 static void
3227   vl_api_one_eid_table_map_details_t_handler_json
3228   (vl_api_one_eid_table_map_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231   vat_json_node_t *node = NULL;
3232
3233   if (VAT_JSON_ARRAY != vam->json_tree.type)
3234     {
3235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3236       vat_json_init_array (&vam->json_tree);
3237     }
3238   node = vat_json_array_add (&vam->json_tree);
3239   vat_json_init_object (node);
3240   vat_json_object_add_uint (node, "dp_table",
3241                             clib_net_to_host_u32 (mp->dp_table));
3242   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3243 }
3244
3245 static void
3246   vl_api_one_eid_table_vni_details_t_handler
3247   (vl_api_one_eid_table_vni_details_t * mp)
3248 {
3249   vat_main_t *vam = &vat_main;
3250
3251   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3252   print (vam->ofp, "%v", line);
3253   vec_free (line);
3254 }
3255
3256 static void
3257   vl_api_one_eid_table_vni_details_t_handler_json
3258   (vl_api_one_eid_table_vni_details_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   vat_json_node_t *node = NULL;
3262
3263   if (VAT_JSON_ARRAY != vam->json_tree.type)
3264     {
3265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3266       vat_json_init_array (&vam->json_tree);
3267     }
3268   node = vat_json_array_add (&vam->json_tree);
3269   vat_json_init_object (node);
3270   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3271 }
3272
3273 static void
3274   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3275   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3281   print (vam->ofp, "fallback threshold value: %d", mp->value);
3282
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3289   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t _node, *node = &_node;
3293   int retval = clib_net_to_host_u32 (mp->retval);
3294
3295   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3296   vat_json_init_object (node);
3297   vat_json_object_add_uint (node, "value", mp->value);
3298
3299   vat_json_print (vam->ofp, node);
3300   vat_json_free (node);
3301
3302   vam->retval = retval;
3303   vam->result_ready = 1;
3304 }
3305
3306 static void
3307   vl_api_show_one_map_register_state_reply_t_handler
3308   (vl_api_show_one_map_register_state_reply_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   int retval = clib_net_to_host_u32 (mp->retval);
3312
3313   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317 }
3318
3319 static void
3320   vl_api_show_one_map_register_state_reply_t_handler_json
3321   (vl_api_show_one_map_register_state_reply_t * mp)
3322 {
3323   vat_main_t *vam = &vat_main;
3324   vat_json_node_t _node, *node = &_node;
3325   int retval = clib_net_to_host_u32 (mp->retval);
3326
3327   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_string_copy (node, "state", s);
3331
3332   vat_json_print (vam->ofp, node);
3333   vat_json_free (node);
3334
3335   vam->retval = retval;
3336   vam->result_ready = 1;
3337   vec_free (s);
3338 }
3339
3340 static void
3341   vl_api_show_one_rloc_probe_state_reply_t_handler
3342   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345   int retval = clib_net_to_host_u32 (mp->retval);
3346
3347   if (retval)
3348     goto end;
3349
3350   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3351 end:
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3358   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   vat_json_node_t _node, *node = &_node;
3362   int retval = clib_net_to_host_u32 (mp->retval);
3363
3364   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3365   vat_json_init_object (node);
3366   vat_json_object_add_string_copy (node, "state", s);
3367
3368   vat_json_print (vam->ofp, node);
3369   vat_json_free (node);
3370
3371   vam->retval = retval;
3372   vam->result_ready = 1;
3373   vec_free (s);
3374 }
3375
3376 static void
3377   vl_api_show_one_stats_enable_disable_reply_t_handler
3378   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   int retval = clib_net_to_host_u32 (mp->retval);
3382
3383   if (retval)
3384     goto end;
3385
3386   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3387 end:
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3394   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397   vat_json_node_t _node, *node = &_node;
3398   int retval = clib_net_to_host_u32 (mp->retval);
3399
3400   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3401   vat_json_init_object (node);
3402   vat_json_object_add_string_copy (node, "state", s);
3403
3404   vat_json_print (vam->ofp, node);
3405   vat_json_free (node);
3406
3407   vam->retval = retval;
3408   vam->result_ready = 1;
3409   vec_free (s);
3410 }
3411
3412 static void
3413 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3414 {
3415   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3416   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3417   e->vni = clib_net_to_host_u32 (e->vni);
3418 }
3419
3420 static void
3421   gpe_fwd_entries_get_reply_t_net_to_host
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   u32 i;
3425
3426   mp->count = clib_net_to_host_u32 (mp->count);
3427   for (i = 0; i < mp->count; i++)
3428     {
3429       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3430     }
3431 }
3432
3433 static u8 *
3434 format_gpe_encap_mode (u8 * s, va_list * args)
3435 {
3436   u32 mode = va_arg (*args, u32);
3437
3438   switch (mode)
3439     {
3440     case 0:
3441       return format (s, "lisp");
3442     case 1:
3443       return format (s, "vxlan");
3444     }
3445   return 0;
3446 }
3447
3448 static void
3449   vl_api_gpe_get_encap_mode_reply_t_handler
3450   (vl_api_gpe_get_encap_mode_reply_t * mp)
3451 {
3452   vat_main_t *vam = &vat_main;
3453
3454   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3455   vam->retval = ntohl (mp->retval);
3456   vam->result_ready = 1;
3457 }
3458
3459 static void
3460   vl_api_gpe_get_encap_mode_reply_t_handler_json
3461   (vl_api_gpe_get_encap_mode_reply_t * mp)
3462 {
3463   vat_main_t *vam = &vat_main;
3464   vat_json_node_t node;
3465
3466   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3467   vec_add1 (encap_mode, 0);
3468
3469   vat_json_init_object (&node);
3470   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3471
3472   vec_free (encap_mode);
3473   vat_json_print (vam->ofp, &node);
3474   vat_json_free (&node);
3475
3476   vam->retval = ntohl (mp->retval);
3477   vam->result_ready = 1;
3478 }
3479
3480 static void
3481   vl_api_gpe_fwd_entry_path_details_t_handler
3482   (vl_api_gpe_fwd_entry_path_details_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3486
3487   if (mp->lcl_loc.is_ip4)
3488     format_ip_address_fcn = format_ip4_address;
3489   else
3490     format_ip_address_fcn = format_ip6_address;
3491
3492   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3493          format_ip_address_fcn, &mp->lcl_loc,
3494          format_ip_address_fcn, &mp->rmt_loc);
3495 }
3496
3497 static void
3498 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3499 {
3500   struct in6_addr ip6;
3501   struct in_addr ip4;
3502
3503   if (loc->is_ip4)
3504     {
3505       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3506       vat_json_object_add_ip4 (n, "address", ip4);
3507     }
3508   else
3509     {
3510       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3511       vat_json_object_add_ip6 (n, "address", ip6);
3512     }
3513   vat_json_object_add_uint (n, "weight", loc->weight);
3514 }
3515
3516 static void
3517   vl_api_gpe_fwd_entry_path_details_t_handler_json
3518   (vl_api_gpe_fwd_entry_path_details_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   vat_json_node_t *node = NULL;
3522   vat_json_node_t *loc_node;
3523
3524   if (VAT_JSON_ARRAY != vam->json_tree.type)
3525     {
3526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3527       vat_json_init_array (&vam->json_tree);
3528     }
3529   node = vat_json_array_add (&vam->json_tree);
3530   vat_json_init_object (node);
3531
3532   loc_node = vat_json_object_add (node, "local_locator");
3533   vat_json_init_object (loc_node);
3534   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3535
3536   loc_node = vat_json_object_add (node, "remote_locator");
3537   vat_json_init_object (loc_node);
3538   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3539 }
3540
3541 static void
3542   vl_api_gpe_fwd_entries_get_reply_t_handler
3543   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3544 {
3545   vat_main_t *vam = &vat_main;
3546   u32 i;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_gpe_fwd_entry_t *e;
3549
3550   if (retval)
3551     goto end;
3552
3553   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3554
3555   for (i = 0; i < mp->count; i++)
3556     {
3557       e = &mp->entries[i];
3558       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3559              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3560              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3561     }
3562
3563 end:
3564   vam->retval = retval;
3565   vam->result_ready = 1;
3566 }
3567
3568 static void
3569   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3570   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3571 {
3572   u8 *s = 0;
3573   vat_main_t *vam = &vat_main;
3574   vat_json_node_t *e = 0, root;
3575   u32 i;
3576   int retval = clib_net_to_host_u32 (mp->retval);
3577   vl_api_gpe_fwd_entry_t *fwd;
3578
3579   if (retval)
3580     goto end;
3581
3582   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3583   vat_json_init_array (&root);
3584
3585   for (i = 0; i < mp->count; i++)
3586     {
3587       e = vat_json_array_add (&root);
3588       fwd = &mp->entries[i];
3589
3590       vat_json_init_object (e);
3591       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3592       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3593       vat_json_object_add_int (e, "vni", fwd->vni);
3594       vat_json_object_add_int (e, "action", fwd->action);
3595
3596       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3597                   fwd->leid_prefix_len);
3598       vec_add1 (s, 0);
3599       vat_json_object_add_string_copy (e, "leid", s);
3600       vec_free (s);
3601
3602       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3603                   fwd->reid_prefix_len);
3604       vec_add1 (s, 0);
3605       vat_json_object_add_string_copy (e, "reid", s);
3606       vec_free (s);
3607     }
3608
3609   vat_json_print (vam->ofp, &root);
3610   vat_json_free (&root);
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3619   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   u32 i, n;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624   vl_api_gpe_native_fwd_rpath_t *r;
3625
3626   if (retval)
3627     goto end;
3628
3629   n = clib_net_to_host_u32 (mp->count);
3630
3631   for (i = 0; i < n; i++)
3632     {
3633       r = &mp->entries[i];
3634       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3635              clib_net_to_host_u32 (r->fib_index),
3636              clib_net_to_host_u32 (r->nh_sw_if_index),
3637              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3638     }
3639
3640 end:
3641   vam->retval = retval;
3642   vam->result_ready = 1;
3643 }
3644
3645 static void
3646   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3647   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3648 {
3649   vat_main_t *vam = &vat_main;
3650   vat_json_node_t root, *e;
3651   u32 i, n;
3652   int retval = clib_net_to_host_u32 (mp->retval);
3653   vl_api_gpe_native_fwd_rpath_t *r;
3654   u8 *s;
3655
3656   if (retval)
3657     goto end;
3658
3659   n = clib_net_to_host_u32 (mp->count);
3660   vat_json_init_array (&root);
3661
3662   for (i = 0; i < n; i++)
3663     {
3664       e = vat_json_array_add (&root);
3665       vat_json_init_object (e);
3666       r = &mp->entries[i];
3667       s =
3668         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3669                 r->nh_addr);
3670       vec_add1 (s, 0);
3671       vat_json_object_add_string_copy (e, "ip4", s);
3672       vec_free (s);
3673
3674       vat_json_object_add_uint (e, "fib_index",
3675                                 clib_net_to_host_u32 (r->fib_index));
3676       vat_json_object_add_uint (e, "nh_sw_if_index",
3677                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3678     }
3679
3680   vat_json_print (vam->ofp, &root);
3681   vat_json_free (&root);
3682
3683 end:
3684   vam->retval = retval;
3685   vam->result_ready = 1;
3686 }
3687
3688 static void
3689   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3690   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3691 {
3692   vat_main_t *vam = &vat_main;
3693   u32 i, n;
3694   int retval = clib_net_to_host_u32 (mp->retval);
3695
3696   if (retval)
3697     goto end;
3698
3699   n = clib_net_to_host_u32 (mp->count);
3700
3701   for (i = 0; i < n; i++)
3702     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3711   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   vat_json_node_t root;
3715   u32 i, n;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722   vat_json_init_array (&root);
3723
3724   for (i = 0; i < n; i++)
3725     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3726
3727   vat_json_print (vam->ofp, &root);
3728   vat_json_free (&root);
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_one_ndp_entries_get_reply_t_handler
3737   (vl_api_one_ndp_entries_get_reply_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   u32 i, n;
3741   int retval = clib_net_to_host_u32 (mp->retval);
3742
3743   if (retval)
3744     goto end;
3745
3746   n = clib_net_to_host_u32 (mp->count);
3747
3748   for (i = 0; i < n; i++)
3749     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3750            format_ethernet_address, mp->entries[i].mac);
3751
3752 end:
3753   vam->retval = retval;
3754   vam->result_ready = 1;
3755 }
3756
3757 static void
3758   vl_api_one_ndp_entries_get_reply_t_handler_json
3759   (vl_api_one_ndp_entries_get_reply_t * mp)
3760 {
3761   u8 *s = 0;
3762   vat_main_t *vam = &vat_main;
3763   vat_json_node_t *e = 0, root;
3764   u32 i, n;
3765   int retval = clib_net_to_host_u32 (mp->retval);
3766   vl_api_one_ndp_entry_t *arp_entry;
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     {
3776       e = vat_json_array_add (&root);
3777       arp_entry = &mp->entries[i];
3778
3779       vat_json_init_object (e);
3780       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3781       vec_add1 (s, 0);
3782
3783       vat_json_object_add_string_copy (e, "mac", s);
3784       vec_free (s);
3785
3786       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3787       vec_add1 (s, 0);
3788       vat_json_object_add_string_copy (e, "ip6", s);
3789       vec_free (s);
3790     }
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_l2_arp_entries_get_reply_t_handler
3802   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3815            format_ethernet_address, mp->entries[i].mac);
3816
3817 end:
3818   vam->retval = retval;
3819   vam->result_ready = 1;
3820 }
3821
3822 static void
3823   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3824   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3825 {
3826   u8 *s = 0;
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t *e = 0, root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831   vl_api_one_l2_arp_entry_t *arp_entry;
3832
3833   if (retval)
3834     goto end;
3835
3836   n = clib_net_to_host_u32 (mp->count);
3837   vat_json_init_array (&root);
3838
3839   for (i = 0; i < n; i++)
3840     {
3841       e = vat_json_array_add (&root);
3842       arp_entry = &mp->entries[i];
3843
3844       vat_json_init_object (e);
3845       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3846       vec_add1 (s, 0);
3847
3848       vat_json_object_add_string_copy (e, "mac", s);
3849       vec_free (s);
3850
3851       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3852       vec_add1 (s, 0);
3853       vat_json_object_add_string_copy (e, "ip4", s);
3854       vec_free (s);
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   u32 i, n;
3870   int retval = clib_net_to_host_u32 (mp->retval);
3871
3872   if (retval)
3873     goto end;
3874
3875   n = clib_net_to_host_u32 (mp->count);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3880     }
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_ndp_bd_get_reply_t_handler_json
3889   (vl_api_one_ndp_bd_get_reply_t * mp)
3890 {
3891   vat_main_t *vam = &vat_main;
3892   vat_json_node_t root;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895
3896   if (retval)
3897     goto end;
3898
3899   n = clib_net_to_host_u32 (mp->count);
3900   vat_json_init_array (&root);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       vat_json_array_add_uint (&root,
3905                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3906     }
3907
3908   vat_json_print (vam->ofp, &root);
3909   vat_json_free (&root);
3910
3911 end:
3912   vam->retval = retval;
3913   vam->result_ready = 1;
3914 }
3915
3916 static void
3917   vl_api_one_l2_arp_bd_get_reply_t_handler
3918   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3919 {
3920   vat_main_t *vam = &vat_main;
3921   u32 i, n;
3922   int retval = clib_net_to_host_u32 (mp->retval);
3923
3924   if (retval)
3925     goto end;
3926
3927   n = clib_net_to_host_u32 (mp->count);
3928
3929   for (i = 0; i < n; i++)
3930     {
3931       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3932     }
3933
3934 end:
3935   vam->retval = retval;
3936   vam->result_ready = 1;
3937 }
3938
3939 static void
3940   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3941   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3942 {
3943   vat_main_t *vam = &vat_main;
3944   vat_json_node_t root;
3945   u32 i, n;
3946   int retval = clib_net_to_host_u32 (mp->retval);
3947
3948   if (retval)
3949     goto end;
3950
3951   n = clib_net_to_host_u32 (mp->count);
3952   vat_json_init_array (&root);
3953
3954   for (i = 0; i < n; i++)
3955     {
3956       vat_json_array_add_uint (&root,
3957                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3958     }
3959
3960   vat_json_print (vam->ofp, &root);
3961   vat_json_free (&root);
3962
3963 end:
3964   vam->retval = retval;
3965   vam->result_ready = 1;
3966 }
3967
3968 static void
3969   vl_api_one_adjacencies_get_reply_t_handler
3970   (vl_api_one_adjacencies_get_reply_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   u32 i, n;
3974   int retval = clib_net_to_host_u32 (mp->retval);
3975   vl_api_one_adjacency_t *a;
3976
3977   if (retval)
3978     goto end;
3979
3980   n = clib_net_to_host_u32 (mp->count);
3981
3982   for (i = 0; i < n; i++)
3983     {
3984       a = &mp->adjacencies[i];
3985       print (vam->ofp, "%U %40U",
3986              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3987              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3988     }
3989
3990 end:
3991   vam->retval = retval;
3992   vam->result_ready = 1;
3993 }
3994
3995 static void
3996   vl_api_one_adjacencies_get_reply_t_handler_json
3997   (vl_api_one_adjacencies_get_reply_t * mp)
3998 {
3999   u8 *s = 0;
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *e = 0, root;
4002   u32 i, n;
4003   int retval = clib_net_to_host_u32 (mp->retval);
4004   vl_api_one_adjacency_t *a;
4005
4006   if (retval)
4007     goto end;
4008
4009   n = clib_net_to_host_u32 (mp->count);
4010   vat_json_init_array (&root);
4011
4012   for (i = 0; i < n; i++)
4013     {
4014       e = vat_json_array_add (&root);
4015       a = &mp->adjacencies[i];
4016
4017       vat_json_init_object (e);
4018       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4019                   a->leid_prefix_len);
4020       vec_add1 (s, 0);
4021       vat_json_object_add_string_copy (e, "leid", s);
4022       vec_free (s);
4023
4024       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4025                   a->reid_prefix_len);
4026       vec_add1 (s, 0);
4027       vat_json_object_add_string_copy (e, "reid", s);
4028       vec_free (s);
4029     }
4030
4031   vat_json_print (vam->ofp, &root);
4032   vat_json_free (&root);
4033
4034 end:
4035   vam->retval = retval;
4036   vam->result_ready = 1;
4037 }
4038
4039 static void
4040 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4041 {
4042   vat_main_t *vam = &vat_main;
4043
4044   print (vam->ofp, "%=20U",
4045          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4046          mp->ip_address);
4047 }
4048
4049 static void
4050   vl_api_one_map_server_details_t_handler_json
4051   (vl_api_one_map_server_details_t * mp)
4052 {
4053   vat_main_t *vam = &vat_main;
4054   vat_json_node_t *node = NULL;
4055   struct in6_addr ip6;
4056   struct in_addr ip4;
4057
4058   if (VAT_JSON_ARRAY != vam->json_tree.type)
4059     {
4060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4061       vat_json_init_array (&vam->json_tree);
4062     }
4063   node = vat_json_array_add (&vam->json_tree);
4064
4065   vat_json_init_object (node);
4066   if (mp->is_ipv6)
4067     {
4068       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4069       vat_json_object_add_ip6 (node, "map-server", ip6);
4070     }
4071   else
4072     {
4073       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4074       vat_json_object_add_ip4 (node, "map-server", ip4);
4075     }
4076 }
4077
4078 static void
4079 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4080                                            * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083
4084   print (vam->ofp, "%=20U",
4085          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4086          mp->ip_address);
4087 }
4088
4089 static void
4090   vl_api_one_map_resolver_details_t_handler_json
4091   (vl_api_one_map_resolver_details_t * mp)
4092 {
4093   vat_main_t *vam = &vat_main;
4094   vat_json_node_t *node = NULL;
4095   struct in6_addr ip6;
4096   struct in_addr ip4;
4097
4098   if (VAT_JSON_ARRAY != vam->json_tree.type)
4099     {
4100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4101       vat_json_init_array (&vam->json_tree);
4102     }
4103   node = vat_json_array_add (&vam->json_tree);
4104
4105   vat_json_init_object (node);
4106   if (mp->is_ipv6)
4107     {
4108       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4109       vat_json_object_add_ip6 (node, "map resolver", ip6);
4110     }
4111   else
4112     {
4113       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4114       vat_json_object_add_ip4 (node, "map resolver", ip4);
4115     }
4116 }
4117
4118 static void
4119 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   i32 retval = ntohl (mp->retval);
4123
4124   if (0 <= retval)
4125     {
4126       print (vam->ofp, "feature: %s\ngpe: %s",
4127              mp->feature_status ? "enabled" : "disabled",
4128              mp->gpe_status ? "enabled" : "disabled");
4129     }
4130
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_show_one_status_reply_t_handler_json
4137   (vl_api_show_one_status_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   vat_json_node_t node;
4141   u8 *gpe_status = NULL;
4142   u8 *feature_status = NULL;
4143
4144   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4145   feature_status = format (0, "%s",
4146                            mp->feature_status ? "enabled" : "disabled");
4147   vec_add1 (gpe_status, 0);
4148   vec_add1 (feature_status, 0);
4149
4150   vat_json_init_object (&node);
4151   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4152   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4153
4154   vec_free (gpe_status);
4155   vec_free (feature_status);
4156
4157   vat_json_print (vam->ofp, &node);
4158   vat_json_free (&node);
4159
4160   vam->retval = ntohl (mp->retval);
4161   vam->result_ready = 1;
4162 }
4163
4164 static void
4165   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4166   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4167 {
4168   vat_main_t *vam = &vat_main;
4169   i32 retval = ntohl (mp->retval);
4170
4171   if (retval >= 0)
4172     {
4173       print (vam->ofp, "%=20s", mp->locator_set_name);
4174     }
4175
4176   vam->retval = retval;
4177   vam->result_ready = 1;
4178 }
4179
4180 static void
4181   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4182   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   vat_json_node_t *node = NULL;
4186
4187   if (VAT_JSON_ARRAY != vam->json_tree.type)
4188     {
4189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4190       vat_json_init_array (&vam->json_tree);
4191     }
4192   node = vat_json_array_add (&vam->json_tree);
4193
4194   vat_json_init_object (node);
4195   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4196
4197   vat_json_print (vam->ofp, node);
4198   vat_json_free (node);
4199
4200   vam->retval = ntohl (mp->retval);
4201   vam->result_ready = 1;
4202 }
4203
4204 static u8 *
4205 format_lisp_map_request_mode (u8 * s, va_list * args)
4206 {
4207   u32 mode = va_arg (*args, u32);
4208
4209   switch (mode)
4210     {
4211     case 0:
4212       return format (0, "dst-only");
4213     case 1:
4214       return format (0, "src-dst");
4215     }
4216   return 0;
4217 }
4218
4219 static void
4220   vl_api_show_one_map_request_mode_reply_t_handler
4221   (vl_api_show_one_map_request_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   i32 retval = ntohl (mp->retval);
4225
4226   if (0 <= retval)
4227     {
4228       u32 mode = mp->mode;
4229       print (vam->ofp, "map_request_mode: %U",
4230              format_lisp_map_request_mode, mode);
4231     }
4232
4233   vam->retval = retval;
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_show_one_map_request_mode_reply_t_handler_json
4239   (vl_api_show_one_map_request_mode_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   vat_json_node_t node;
4243   u8 *s = 0;
4244   u32 mode;
4245
4246   mode = mp->mode;
4247   s = format (0, "%U", format_lisp_map_request_mode, mode);
4248   vec_add1 (s, 0);
4249
4250   vat_json_init_object (&node);
4251   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4252   vat_json_print (vam->ofp, &node);
4253   vat_json_free (&node);
4254
4255   vec_free (s);
4256   vam->retval = ntohl (mp->retval);
4257   vam->result_ready = 1;
4258 }
4259
4260 static void
4261   vl_api_one_show_xtr_mode_reply_t_handler
4262   (vl_api_one_show_xtr_mode_reply_t * mp)
4263 {
4264   vat_main_t *vam = &vat_main;
4265   i32 retval = ntohl (mp->retval);
4266
4267   if (0 <= retval)
4268     {
4269       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4270     }
4271
4272   vam->retval = retval;
4273   vam->result_ready = 1;
4274 }
4275
4276 static void
4277   vl_api_one_show_xtr_mode_reply_t_handler_json
4278   (vl_api_one_show_xtr_mode_reply_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281   vat_json_node_t node;
4282   u8 *status = 0;
4283
4284   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4285   vec_add1 (status, 0);
4286
4287   vat_json_init_object (&node);
4288   vat_json_object_add_string_copy (&node, "status", status);
4289
4290   vec_free (status);
4291
4292   vat_json_print (vam->ofp, &node);
4293   vat_json_free (&node);
4294
4295   vam->retval = ntohl (mp->retval);
4296   vam->result_ready = 1;
4297 }
4298
4299 static void
4300   vl_api_one_show_pitr_mode_reply_t_handler
4301   (vl_api_one_show_pitr_mode_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   i32 retval = ntohl (mp->retval);
4305
4306   if (0 <= retval)
4307     {
4308       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4309     }
4310
4311   vam->retval = retval;
4312   vam->result_ready = 1;
4313 }
4314
4315 static void
4316   vl_api_one_show_pitr_mode_reply_t_handler_json
4317   (vl_api_one_show_pitr_mode_reply_t * mp)
4318 {
4319   vat_main_t *vam = &vat_main;
4320   vat_json_node_t node;
4321   u8 *status = 0;
4322
4323   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4324   vec_add1 (status, 0);
4325
4326   vat_json_init_object (&node);
4327   vat_json_object_add_string_copy (&node, "status", status);
4328
4329   vec_free (status);
4330
4331   vat_json_print (vam->ofp, &node);
4332   vat_json_free (&node);
4333
4334   vam->retval = ntohl (mp->retval);
4335   vam->result_ready = 1;
4336 }
4337
4338 static void
4339   vl_api_one_show_petr_mode_reply_t_handler
4340   (vl_api_one_show_petr_mode_reply_t * mp)
4341 {
4342   vat_main_t *vam = &vat_main;
4343   i32 retval = ntohl (mp->retval);
4344
4345   if (0 <= retval)
4346     {
4347       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4348     }
4349
4350   vam->retval = retval;
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355   vl_api_one_show_petr_mode_reply_t_handler_json
4356   (vl_api_one_show_petr_mode_reply_t * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359   vat_json_node_t node;
4360   u8 *status = 0;
4361
4362   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4363   vec_add1 (status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "status", status);
4367
4368   vec_free (status);
4369
4370   vat_json_print (vam->ofp, &node);
4371   vat_json_free (&node);
4372
4373   vam->retval = ntohl (mp->retval);
4374   vam->result_ready = 1;
4375 }
4376
4377 static void
4378   vl_api_show_one_use_petr_reply_t_handler
4379   (vl_api_show_one_use_petr_reply_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   i32 retval = ntohl (mp->retval);
4383
4384   if (0 <= retval)
4385     {
4386       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4387       if (mp->status)
4388         {
4389           print (vam->ofp, "Proxy-ETR address; %U",
4390                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4391                  mp->address);
4392         }
4393     }
4394
4395   vam->retval = retval;
4396   vam->result_ready = 1;
4397 }
4398
4399 static void
4400   vl_api_show_one_use_petr_reply_t_handler_json
4401   (vl_api_show_one_use_petr_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406   struct in_addr ip4;
4407   struct in6_addr ip6;
4408
4409   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4410   vec_add1 (status, 0);
4411
4412   vat_json_init_object (&node);
4413   vat_json_object_add_string_copy (&node, "status", status);
4414   if (mp->status)
4415     {
4416       if (mp->is_ip4)
4417         {
4418           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4419           vat_json_object_add_ip6 (&node, "address", ip6);
4420         }
4421       else
4422         {
4423           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4424           vat_json_object_add_ip4 (&node, "address", ip4);
4425         }
4426     }
4427
4428   vec_free (status);
4429
4430   vat_json_print (vam->ofp, &node);
4431   vat_json_free (&node);
4432
4433   vam->retval = ntohl (mp->retval);
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_nsh_mapping_reply_t_handler
4439   (vl_api_show_one_nsh_mapping_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   i32 retval = ntohl (mp->retval);
4443
4444   if (0 <= retval)
4445     {
4446       print (vam->ofp, "%-20s%-16s",
4447              mp->is_set ? "set" : "not-set",
4448              mp->is_set ? (char *) mp->locator_set_name : "");
4449     }
4450
4451   vam->retval = retval;
4452   vam->result_ready = 1;
4453 }
4454
4455 static void
4456   vl_api_show_one_nsh_mapping_reply_t_handler_json
4457   (vl_api_show_one_nsh_mapping_reply_t * mp)
4458 {
4459   vat_main_t *vam = &vat_main;
4460   vat_json_node_t node;
4461   u8 *status = 0;
4462
4463   status = format (0, "%s", mp->is_set ? "yes" : "no");
4464   vec_add1 (status, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "is_set", status);
4468   if (mp->is_set)
4469     {
4470       vat_json_object_add_string_copy (&node, "locator_set",
4471                                        mp->locator_set_name);
4472     }
4473
4474   vec_free (status);
4475
4476   vat_json_print (vam->ofp, &node);
4477   vat_json_free (&node);
4478
4479   vam->retval = ntohl (mp->retval);
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_show_one_map_register_ttl_reply_t_handler
4485   (vl_api_show_one_map_register_ttl_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   i32 retval = ntohl (mp->retval);
4489
4490   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4491
4492   if (0 <= retval)
4493     {
4494       print (vam->ofp, "ttl: %u", mp->ttl);
4495     }
4496
4497   vam->retval = retval;
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502   vl_api_show_one_map_register_ttl_reply_t_handler_json
4503   (vl_api_show_one_map_register_ttl_reply_t * mp)
4504 {
4505   vat_main_t *vam = &vat_main;
4506   vat_json_node_t node;
4507
4508   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4509   vat_json_init_object (&node);
4510   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4511
4512   vat_json_print (vam->ofp, &node);
4513   vat_json_free (&node);
4514
4515   vam->retval = ntohl (mp->retval);
4516   vam->result_ready = 1;
4517 }
4518
4519 static void
4520 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4521 {
4522   vat_main_t *vam = &vat_main;
4523   i32 retval = ntohl (mp->retval);
4524
4525   if (0 <= retval)
4526     {
4527       print (vam->ofp, "%-20s%-16s",
4528              mp->status ? "enabled" : "disabled",
4529              mp->status ? (char *) mp->locator_set_name : "");
4530     }
4531
4532   vam->retval = retval;
4533   vam->result_ready = 1;
4534 }
4535
4536 static void
4537 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4538 {
4539   vat_main_t *vam = &vat_main;
4540   vat_json_node_t node;
4541   u8 *status = 0;
4542
4543   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4544   vec_add1 (status, 0);
4545
4546   vat_json_init_object (&node);
4547   vat_json_object_add_string_copy (&node, "status", status);
4548   if (mp->status)
4549     {
4550       vat_json_object_add_string_copy (&node, "locator_set",
4551                                        mp->locator_set_name);
4552     }
4553
4554   vec_free (status);
4555
4556   vat_json_print (vam->ofp, &node);
4557   vat_json_free (&node);
4558
4559   vam->retval = ntohl (mp->retval);
4560   vam->result_ready = 1;
4561 }
4562
4563 static u8 *
4564 format_policer_type (u8 * s, va_list * va)
4565 {
4566   u32 i = va_arg (*va, u32);
4567
4568   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4569     s = format (s, "1r2c");
4570   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4571     s = format (s, "1r3c");
4572   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4573     s = format (s, "2r3c-2698");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4575     s = format (s, "2r3c-4115");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4577     s = format (s, "2r3c-mef5cf1");
4578   else
4579     s = format (s, "ILLEGAL");
4580   return s;
4581 }
4582
4583 static u8 *
4584 format_policer_rate_type (u8 * s, va_list * va)
4585 {
4586   u32 i = va_arg (*va, u32);
4587
4588   if (i == SSE2_QOS_RATE_KBPS)
4589     s = format (s, "kbps");
4590   else if (i == SSE2_QOS_RATE_PPS)
4591     s = format (s, "pps");
4592   else
4593     s = format (s, "ILLEGAL");
4594   return s;
4595 }
4596
4597 static u8 *
4598 format_policer_round_type (u8 * s, va_list * va)
4599 {
4600   u32 i = va_arg (*va, u32);
4601
4602   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4603     s = format (s, "closest");
4604   else if (i == SSE2_QOS_ROUND_TO_UP)
4605     s = format (s, "up");
4606   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4607     s = format (s, "down");
4608   else
4609     s = format (s, "ILLEGAL");
4610   return s;
4611 }
4612
4613 static u8 *
4614 format_policer_action_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_ACTION_DROP)
4619     s = format (s, "drop");
4620   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4621     s = format (s, "transmit");
4622   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4623     s = format (s, "mark-and-transmit");
4624   else
4625     s = format (s, "ILLEGAL");
4626   return s;
4627 }
4628
4629 static u8 *
4630 format_dscp (u8 * s, va_list * va)
4631 {
4632   u32 i = va_arg (*va, u32);
4633   char *t = 0;
4634
4635   switch (i)
4636     {
4637 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4638       foreach_vnet_dscp
4639 #undef _
4640     default:
4641       return format (s, "ILLEGAL");
4642     }
4643   s = format (s, "%s", t);
4644   return s;
4645 }
4646
4647 static void
4648 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4649 {
4650   vat_main_t *vam = &vat_main;
4651   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4652
4653   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4654     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4655   else
4656     conform_dscp_str = format (0, "");
4657
4658   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4659     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4660   else
4661     exceed_dscp_str = format (0, "");
4662
4663   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4664     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4665   else
4666     violate_dscp_str = format (0, "");
4667
4668   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4669          "rate type %U, round type %U, %s rate, %s color-aware, "
4670          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4671          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4672          "conform action %U%s, exceed action %U%s, violate action %U%s",
4673          mp->name,
4674          format_policer_type, mp->type,
4675          ntohl (mp->cir),
4676          ntohl (mp->eir),
4677          clib_net_to_host_u64 (mp->cb),
4678          clib_net_to_host_u64 (mp->eb),
4679          format_policer_rate_type, mp->rate_type,
4680          format_policer_round_type, mp->round_type,
4681          mp->single_rate ? "single" : "dual",
4682          mp->color_aware ? "is" : "not",
4683          ntohl (mp->cir_tokens_per_period),
4684          ntohl (mp->pir_tokens_per_period),
4685          ntohl (mp->scale),
4686          ntohl (mp->current_limit),
4687          ntohl (mp->current_bucket),
4688          ntohl (mp->extended_limit),
4689          ntohl (mp->extended_bucket),
4690          clib_net_to_host_u64 (mp->last_update_time),
4691          format_policer_action_type, mp->conform_action_type,
4692          conform_dscp_str,
4693          format_policer_action_type, mp->exceed_action_type,
4694          exceed_dscp_str,
4695          format_policer_action_type, mp->violate_action_type,
4696          violate_dscp_str);
4697
4698   vec_free (conform_dscp_str);
4699   vec_free (exceed_dscp_str);
4700   vec_free (violate_dscp_str);
4701 }
4702
4703 static void vl_api_policer_details_t_handler_json
4704   (vl_api_policer_details_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t *node;
4708   u8 *rate_type_str, *round_type_str, *type_str;
4709   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4710
4711   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4712   round_type_str =
4713     format (0, "%U", format_policer_round_type, mp->round_type);
4714   type_str = format (0, "%U", format_policer_type, mp->type);
4715   conform_action_str = format (0, "%U", format_policer_action_type,
4716                                mp->conform_action_type);
4717   exceed_action_str = format (0, "%U", format_policer_action_type,
4718                               mp->exceed_action_type);
4719   violate_action_str = format (0, "%U", format_policer_action_type,
4720                                mp->violate_action_type);
4721
4722   if (VAT_JSON_ARRAY != vam->json_tree.type)
4723     {
4724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4725       vat_json_init_array (&vam->json_tree);
4726     }
4727   node = vat_json_array_add (&vam->json_tree);
4728
4729   vat_json_init_object (node);
4730   vat_json_object_add_string_copy (node, "name", mp->name);
4731   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4732   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4733   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4734   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4735   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4736   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4737   vat_json_object_add_string_copy (node, "type", type_str);
4738   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4739   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4740   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4741   vat_json_object_add_uint (node, "cir_tokens_per_period",
4742                             ntohl (mp->cir_tokens_per_period));
4743   vat_json_object_add_uint (node, "eir_tokens_per_period",
4744                             ntohl (mp->pir_tokens_per_period));
4745   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4746   vat_json_object_add_uint (node, "current_bucket",
4747                             ntohl (mp->current_bucket));
4748   vat_json_object_add_uint (node, "extended_limit",
4749                             ntohl (mp->extended_limit));
4750   vat_json_object_add_uint (node, "extended_bucket",
4751                             ntohl (mp->extended_bucket));
4752   vat_json_object_add_uint (node, "last_update_time",
4753                             ntohl (mp->last_update_time));
4754   vat_json_object_add_string_copy (node, "conform_action",
4755                                    conform_action_str);
4756   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4757     {
4758       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4759       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4760       vec_free (dscp_str);
4761     }
4762   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4763   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4764     {
4765       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4766       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4767       vec_free (dscp_str);
4768     }
4769   vat_json_object_add_string_copy (node, "violate_action",
4770                                    violate_action_str);
4771   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4772     {
4773       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4774       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4775       vec_free (dscp_str);
4776     }
4777
4778   vec_free (rate_type_str);
4779   vec_free (round_type_str);
4780   vec_free (type_str);
4781   vec_free (conform_action_str);
4782   vec_free (exceed_action_str);
4783   vec_free (violate_action_str);
4784 }
4785
4786 static void
4787 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4788                                            mp)
4789 {
4790   vat_main_t *vam = &vat_main;
4791   int i, count = ntohl (mp->count);
4792
4793   if (count > 0)
4794     print (vam->ofp, "classify table ids (%d) : ", count);
4795   for (i = 0; i < count; i++)
4796     {
4797       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4798       print (vam->ofp, (i < count - 1) ? "," : "");
4799     }
4800   vam->retval = ntohl (mp->retval);
4801   vam->result_ready = 1;
4802 }
4803
4804 static void
4805   vl_api_classify_table_ids_reply_t_handler_json
4806   (vl_api_classify_table_ids_reply_t * mp)
4807 {
4808   vat_main_t *vam = &vat_main;
4809   int i, count = ntohl (mp->count);
4810
4811   if (count > 0)
4812     {
4813       vat_json_node_t node;
4814
4815       vat_json_init_object (&node);
4816       for (i = 0; i < count; i++)
4817         {
4818           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4819         }
4820       vat_json_print (vam->ofp, &node);
4821       vat_json_free (&node);
4822     }
4823   vam->retval = ntohl (mp->retval);
4824   vam->result_ready = 1;
4825 }
4826
4827 static void
4828   vl_api_classify_table_by_interface_reply_t_handler
4829   (vl_api_classify_table_by_interface_reply_t * mp)
4830 {
4831   vat_main_t *vam = &vat_main;
4832   u32 table_id;
4833
4834   table_id = ntohl (mp->l2_table_id);
4835   if (table_id != ~0)
4836     print (vam->ofp, "l2 table id : %d", table_id);
4837   else
4838     print (vam->ofp, "l2 table id : No input ACL tables configured");
4839   table_id = ntohl (mp->ip4_table_id);
4840   if (table_id != ~0)
4841     print (vam->ofp, "ip4 table id : %d", table_id);
4842   else
4843     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4844   table_id = ntohl (mp->ip6_table_id);
4845   if (table_id != ~0)
4846     print (vam->ofp, "ip6 table id : %d", table_id);
4847   else
4848     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4849   vam->retval = ntohl (mp->retval);
4850   vam->result_ready = 1;
4851 }
4852
4853 static void
4854   vl_api_classify_table_by_interface_reply_t_handler_json
4855   (vl_api_classify_table_by_interface_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   vat_json_node_t node;
4859
4860   vat_json_init_object (&node);
4861
4862   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4863   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4864   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4865
4866   vat_json_print (vam->ofp, &node);
4867   vat_json_free (&node);
4868
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void vl_api_policer_add_del_reply_t_handler
4874   (vl_api_policer_add_del_reply_t * mp)
4875 {
4876   vat_main_t *vam = &vat_main;
4877   i32 retval = ntohl (mp->retval);
4878   if (vam->async_mode)
4879     {
4880       vam->async_errors += (retval < 0);
4881     }
4882   else
4883     {
4884       vam->retval = retval;
4885       vam->result_ready = 1;
4886       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4887         /*
4888          * Note: this is just barely thread-safe, depends on
4889          * the main thread spinning waiting for an answer...
4890          */
4891         errmsg ("policer index %d", ntohl (mp->policer_index));
4892     }
4893 }
4894
4895 static void vl_api_policer_add_del_reply_t_handler_json
4896   (vl_api_policer_add_del_reply_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899   vat_json_node_t node;
4900
4901   vat_json_init_object (&node);
4902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4903   vat_json_object_add_uint (&node, "policer_index",
4904                             ntohl (mp->policer_index));
4905
4906   vat_json_print (vam->ofp, &node);
4907   vat_json_free (&node);
4908
4909   vam->retval = ntohl (mp->retval);
4910   vam->result_ready = 1;
4911 }
4912
4913 /* Format hex dump. */
4914 u8 *
4915 format_hex_bytes (u8 * s, va_list * va)
4916 {
4917   u8 *bytes = va_arg (*va, u8 *);
4918   int n_bytes = va_arg (*va, int);
4919   uword i;
4920
4921   /* Print short or long form depending on byte count. */
4922   uword short_form = n_bytes <= 32;
4923   u32 indent = format_get_indent (s);
4924
4925   if (n_bytes == 0)
4926     return s;
4927
4928   for (i = 0; i < n_bytes; i++)
4929     {
4930       if (!short_form && (i % 32) == 0)
4931         s = format (s, "%08x: ", i);
4932       s = format (s, "%02x", bytes[i]);
4933       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4934         s = format (s, "\n%U", format_white_space, indent);
4935     }
4936
4937   return s;
4938 }
4939
4940 static void
4941 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4942                                             * mp)
4943 {
4944   vat_main_t *vam = &vat_main;
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       print (vam->ofp, "classify table info :");
4949       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4950              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4951              ntohl (mp->miss_next_index));
4952       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4953              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4954              ntohl (mp->match_n_vectors));
4955       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4956              ntohl (mp->mask_length));
4957     }
4958   vam->retval = retval;
4959   vam->result_ready = 1;
4960 }
4961
4962 static void
4963   vl_api_classify_table_info_reply_t_handler_json
4964   (vl_api_classify_table_info_reply_t * mp)
4965 {
4966   vat_main_t *vam = &vat_main;
4967   vat_json_node_t node;
4968
4969   i32 retval = ntohl (mp->retval);
4970   if (retval == 0)
4971     {
4972       vat_json_init_object (&node);
4973
4974       vat_json_object_add_int (&node, "sessions",
4975                                ntohl (mp->active_sessions));
4976       vat_json_object_add_int (&node, "nexttbl",
4977                                ntohl (mp->next_table_index));
4978       vat_json_object_add_int (&node, "nextnode",
4979                                ntohl (mp->miss_next_index));
4980       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4981       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4982       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4983       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4984                       ntohl (mp->mask_length), 0);
4985       vat_json_object_add_string_copy (&node, "mask", s);
4986
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4996                                            mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999
5000   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5001          ntohl (mp->hit_next_index), ntohl (mp->advance),
5002          ntohl (mp->opaque_index));
5003   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5004          ntohl (mp->match_length));
5005 }
5006
5007 static void
5008   vl_api_classify_session_details_t_handler_json
5009   (vl_api_classify_session_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node = NULL;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5023   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5024   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5025   u8 *s =
5026     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5027             0);
5028   vat_json_object_add_string_copy (node, "match", s);
5029 }
5030
5031 static void vl_api_pg_create_interface_reply_t_handler
5032   (vl_api_pg_create_interface_reply_t * mp)
5033 {
5034   vat_main_t *vam = &vat_main;
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_pg_create_interface_reply_t_handler_json
5041   (vl_api_pg_create_interface_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   vat_json_node_t node;
5045
5046   i32 retval = ntohl (mp->retval);
5047   if (retval == 0)
5048     {
5049       vat_json_init_object (&node);
5050
5051       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5052
5053       vat_json_print (vam->ofp, &node);
5054       vat_json_free (&node);
5055     }
5056   vam->retval = ntohl (mp->retval);
5057   vam->result_ready = 1;
5058 }
5059
5060 static void vl_api_policer_classify_details_t_handler
5061   (vl_api_policer_classify_details_t * mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064
5065   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5066          ntohl (mp->table_index));
5067 }
5068
5069 static void vl_api_policer_classify_details_t_handler_json
5070   (vl_api_policer_classify_details_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   vat_json_node_t *node;
5074
5075   if (VAT_JSON_ARRAY != vam->json_tree.type)
5076     {
5077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5078       vat_json_init_array (&vam->json_tree);
5079     }
5080   node = vat_json_array_add (&vam->json_tree);
5081
5082   vat_json_init_object (node);
5083   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5084   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5085 }
5086
5087 static void vl_api_flow_classify_details_t_handler
5088   (vl_api_flow_classify_details_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091
5092   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5093          ntohl (mp->table_index));
5094 }
5095
5096 static void vl_api_flow_classify_details_t_handler_json
5097   (vl_api_flow_classify_details_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100   vat_json_node_t *node;
5101
5102   if (VAT_JSON_ARRAY != vam->json_tree.type)
5103     {
5104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5105       vat_json_init_array (&vam->json_tree);
5106     }
5107   node = vat_json_array_add (&vam->json_tree);
5108
5109   vat_json_init_object (node);
5110   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5111   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5112 }
5113
5114 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5115 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5116 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5117 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5118 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5119 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5121 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5122 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5123 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5124
5125 /*
5126  * Generate boilerplate reply handlers, which
5127  * dig the return value out of the xxx_reply_t API message,
5128  * stick it into vam->retval, and set vam->result_ready
5129  *
5130  * Could also do this by pointing N message decode slots at
5131  * a single function, but that could break in subtle ways.
5132  */
5133
5134 #define foreach_standard_reply_retval_handler           \
5135 _(sw_interface_set_flags_reply)                         \
5136 _(sw_interface_add_del_address_reply)                   \
5137 _(sw_interface_set_rx_mode_reply)                       \
5138 _(sw_interface_set_rx_placement_reply)                  \
5139 _(sw_interface_set_table_reply)                         \
5140 _(sw_interface_set_mpls_enable_reply)                   \
5141 _(sw_interface_set_vpath_reply)                         \
5142 _(sw_interface_set_vxlan_bypass_reply)                  \
5143 _(sw_interface_set_geneve_bypass_reply)                 \
5144 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5145 _(sw_interface_set_l2_bridge_reply)                     \
5146 _(bridge_domain_add_del_reply)                          \
5147 _(sw_interface_set_l2_xconnect_reply)                   \
5148 _(l2fib_add_del_reply)                                  \
5149 _(l2fib_flush_int_reply)                                \
5150 _(l2fib_flush_bd_reply)                                 \
5151 _(ip_route_add_del_reply)                               \
5152 _(ip_table_add_del_reply)                               \
5153 _(ip_mroute_add_del_reply)                              \
5154 _(mpls_route_add_del_reply)                             \
5155 _(mpls_table_add_del_reply)                             \
5156 _(mpls_ip_bind_unbind_reply)                            \
5157 _(bier_route_add_del_reply)                             \
5158 _(bier_table_add_del_reply)                             \
5159 _(proxy_arp_add_del_reply)                              \
5160 _(proxy_arp_intfc_enable_disable_reply)                 \
5161 _(sw_interface_set_unnumbered_reply)                    \
5162 _(ip_neighbor_add_del_reply)                            \
5163 _(reset_fib_reply)                                      \
5164 _(dhcp_proxy_config_reply)                              \
5165 _(dhcp_proxy_set_vss_reply)                             \
5166 _(dhcp_client_config_reply)                             \
5167 _(set_ip_flow_hash_reply)                               \
5168 _(sw_interface_ip6_enable_disable_reply)                \
5169 _(ip6nd_proxy_add_del_reply)                            \
5170 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5171 _(sw_interface_ip6nd_ra_config_reply)                   \
5172 _(set_arp_neighbor_limit_reply)                         \
5173 _(l2_patch_add_del_reply)                               \
5174 _(sr_mpls_policy_add_reply)                             \
5175 _(sr_mpls_policy_mod_reply)                             \
5176 _(sr_mpls_policy_del_reply)                             \
5177 _(sr_policy_add_reply)                                  \
5178 _(sr_policy_mod_reply)                                  \
5179 _(sr_policy_del_reply)                                  \
5180 _(sr_localsid_add_del_reply)                            \
5181 _(sr_steering_add_del_reply)                            \
5182 _(classify_add_del_session_reply)                       \
5183 _(classify_set_interface_ip_table_reply)                \
5184 _(classify_set_interface_l2_tables_reply)               \
5185 _(l2tpv3_set_tunnel_cookies_reply)                      \
5186 _(l2tpv3_interface_enable_disable_reply)                \
5187 _(l2tpv3_set_lookup_key_reply)                          \
5188 _(l2_fib_clear_table_reply)                             \
5189 _(l2_interface_efp_filter_reply)                        \
5190 _(l2_interface_vlan_tag_rewrite_reply)                  \
5191 _(modify_vhost_user_if_reply)                           \
5192 _(delete_vhost_user_if_reply)                           \
5193 _(ip_probe_neighbor_reply)                              \
5194 _(ip_scan_neighbor_enable_disable_reply)                \
5195 _(want_ip4_arp_events_reply)                            \
5196 _(want_ip6_nd_events_reply)                             \
5197 _(want_l2_macs_events_reply)                            \
5198 _(input_acl_set_interface_reply)                        \
5199 _(ipsec_spd_add_del_reply)                              \
5200 _(ipsec_interface_add_del_spd_reply)                    \
5201 _(ipsec_spd_entry_add_del_reply)                        \
5202 _(ipsec_sad_entry_add_del_reply)                        \
5203 _(ipsec_tunnel_if_add_del_reply)                        \
5204 _(ipsec_tunnel_if_set_sa_reply)                         \
5205 _(delete_loopback_reply)                                \
5206 _(bd_ip_mac_add_del_reply)                              \
5207 _(bd_ip_mac_flush_reply)                                \
5208 _(want_interface_events_reply)                          \
5209 _(cop_interface_enable_disable_reply)                   \
5210 _(cop_whitelist_enable_disable_reply)                   \
5211 _(sw_interface_clear_stats_reply)                       \
5212 _(ioam_enable_reply)                                    \
5213 _(ioam_disable_reply)                                   \
5214 _(one_add_del_locator_reply)                            \
5215 _(one_add_del_local_eid_reply)                          \
5216 _(one_add_del_remote_mapping_reply)                     \
5217 _(one_add_del_adjacency_reply)                          \
5218 _(one_add_del_map_resolver_reply)                       \
5219 _(one_add_del_map_server_reply)                         \
5220 _(one_enable_disable_reply)                             \
5221 _(one_rloc_probe_enable_disable_reply)                  \
5222 _(one_map_register_enable_disable_reply)                \
5223 _(one_map_register_set_ttl_reply)                       \
5224 _(one_set_transport_protocol_reply)                     \
5225 _(one_map_register_fallback_threshold_reply)            \
5226 _(one_pitr_set_locator_set_reply)                       \
5227 _(one_map_request_mode_reply)                           \
5228 _(one_add_del_map_request_itr_rlocs_reply)              \
5229 _(one_eid_table_add_del_map_reply)                      \
5230 _(one_use_petr_reply)                                   \
5231 _(one_stats_enable_disable_reply)                       \
5232 _(one_add_del_l2_arp_entry_reply)                       \
5233 _(one_add_del_ndp_entry_reply)                          \
5234 _(one_stats_flush_reply)                                \
5235 _(one_enable_disable_xtr_mode_reply)                    \
5236 _(one_enable_disable_pitr_mode_reply)                   \
5237 _(one_enable_disable_petr_mode_reply)                   \
5238 _(gpe_enable_disable_reply)                             \
5239 _(gpe_set_encap_mode_reply)                             \
5240 _(gpe_add_del_iface_reply)                              \
5241 _(gpe_add_del_native_fwd_rpath_reply)                   \
5242 _(af_packet_delete_reply)                               \
5243 _(policer_classify_set_interface_reply)                 \
5244 _(netmap_create_reply)                                  \
5245 _(netmap_delete_reply)                                  \
5246 _(set_ipfix_exporter_reply)                             \
5247 _(set_ipfix_classify_stream_reply)                      \
5248 _(ipfix_classify_table_add_del_reply)                   \
5249 _(flow_classify_set_interface_reply)                    \
5250 _(sw_interface_span_enable_disable_reply)               \
5251 _(pg_capture_reply)                                     \
5252 _(pg_enable_disable_reply)                              \
5253 _(ip_source_and_port_range_check_add_del_reply)         \
5254 _(ip_source_and_port_range_check_interface_add_del_reply)\
5255 _(delete_subif_reply)                                   \
5256 _(l2_interface_pbb_tag_rewrite_reply)                   \
5257 _(set_punt_reply)                                       \
5258 _(feature_enable_disable_reply)                         \
5259 _(sw_interface_tag_add_del_reply)                       \
5260 _(hw_interface_set_mtu_reply)                           \
5261 _(p2p_ethernet_add_reply)                               \
5262 _(p2p_ethernet_del_reply)                               \
5263 _(lldp_config_reply)                                    \
5264 _(sw_interface_set_lldp_reply)                          \
5265 _(tcp_configure_src_addresses_reply)                    \
5266 _(dns_enable_disable_reply)                             \
5267 _(dns_name_server_add_del_reply)                        \
5268 _(session_rule_add_del_reply)                           \
5269 _(ip_container_proxy_add_del_reply)                     \
5270 _(output_acl_set_interface_reply)                       \
5271 _(qos_record_enable_disable_reply)
5272
5273 #define _(n)                                    \
5274     static void vl_api_##n##_t_handler          \
5275     (vl_api_##n##_t * mp)                       \
5276     {                                           \
5277         vat_main_t * vam = &vat_main;           \
5278         i32 retval = ntohl(mp->retval);         \
5279         if (vam->async_mode) {                  \
5280             vam->async_errors += (retval < 0);  \
5281         } else {                                \
5282             vam->retval = retval;               \
5283             vam->result_ready = 1;              \
5284         }                                       \
5285     }
5286 foreach_standard_reply_retval_handler;
5287 #undef _
5288
5289 #define _(n)                                    \
5290     static void vl_api_##n##_t_handler_json     \
5291     (vl_api_##n##_t * mp)                       \
5292     {                                           \
5293         vat_main_t * vam = &vat_main;           \
5294         vat_json_node_t node;                   \
5295         vat_json_init_object(&node);            \
5296         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5297         vat_json_print(vam->ofp, &node);        \
5298         vam->retval = ntohl(mp->retval);        \
5299         vam->result_ready = 1;                  \
5300     }
5301 foreach_standard_reply_retval_handler;
5302 #undef _
5303
5304 /*
5305  * Table of message reply handlers, must include boilerplate handlers
5306  * we just generated
5307  */
5308
5309 #define foreach_vpe_api_reply_msg                                       \
5310 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5311 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5312 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5313 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5314 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5315 _(CLI_REPLY, cli_reply)                                                 \
5316 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5317 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5318   sw_interface_add_del_address_reply)                                   \
5319 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5320 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5321 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5322 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5323 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5324 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5325 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5326 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5327 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5328 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5329   sw_interface_set_l2_xconnect_reply)                                   \
5330 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5331   sw_interface_set_l2_bridge_reply)                                     \
5332 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5333 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5334 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5335 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5336 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5337 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5338 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5339 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5340 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5341 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5342 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5343 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5344 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5345 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5346 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5347 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5348 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5349 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5350 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5351 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5352 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5353 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5354 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5355 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5356 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5357 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5358 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5359 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5360 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5361 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5362   proxy_arp_intfc_enable_disable_reply)                                 \
5363 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5364 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5365   sw_interface_set_unnumbered_reply)                                    \
5366 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5367 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5368 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5369 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5370 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5371 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5372 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5373 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5374 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5375 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5376   sw_interface_ip6_enable_disable_reply)                                \
5377 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5378 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5379 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5380   sw_interface_ip6nd_ra_prefix_reply)                                   \
5381 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5382   sw_interface_ip6nd_ra_config_reply)                                   \
5383 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5384 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5385 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5386 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5387 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5388 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5389 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5390 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5391 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5392 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5393 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5394 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5395 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5396 classify_set_interface_ip_table_reply)                                  \
5397 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5398   classify_set_interface_l2_tables_reply)                               \
5399 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5400 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5401 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5402 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5403 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5404   l2tpv3_interface_enable_disable_reply)                                \
5405 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5406 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5407 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5408 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5409 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5410 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5411 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5412 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5413 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5414 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5415 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5416 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5417 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5418 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5419 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5420 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5421 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5422 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5423 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5424 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5425 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5426 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5427 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5428 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5429 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5430 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5431 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5432 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5433 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5434 _(L2_MACS_EVENT, l2_macs_event)                                         \
5435 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5436 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5437 _(IP_DETAILS, ip_details)                                               \
5438 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5439 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5440 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5441 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5442 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5443 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5444 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5445 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5446 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5447 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5448 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5449 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5450 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5451 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5452 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5453 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5454 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5455 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5456 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5457 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5458 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5459 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5460 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5461 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5462 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5463 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5464 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5465 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5466 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5467   one_map_register_enable_disable_reply)                                \
5468 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5469 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5470 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5471 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5472   one_map_register_fallback_threshold_reply)                            \
5473 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5474   one_rloc_probe_enable_disable_reply)                                  \
5475 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5476 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5477 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5478 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5479 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5480 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5481 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5482 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5483 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5484 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5485 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5486 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5487 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5488 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5489 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5490 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5491   show_one_stats_enable_disable_reply)                                  \
5492 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5493 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5494 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5495 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5496 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5497 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5498 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5499 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5500   one_enable_disable_pitr_mode_reply)                                   \
5501 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5502   one_enable_disable_petr_mode_reply)                                   \
5503 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5504 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5505 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5506 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5507 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5508 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5509 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5510 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5511 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5512 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5513 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5514 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5515   gpe_add_del_native_fwd_rpath_reply)                                   \
5516 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5517   gpe_fwd_entry_path_details)                                           \
5518 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5519 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5520   one_add_del_map_request_itr_rlocs_reply)                              \
5521 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5522   one_get_map_request_itr_rlocs_reply)                                  \
5523 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5524 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5525 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5526 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5527 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5528 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5529   show_one_map_register_state_reply)                                    \
5530 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5531 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5532   show_one_map_register_fallback_threshold_reply)                       \
5533 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5534 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5535 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5536 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5537 _(POLICER_DETAILS, policer_details)                                     \
5538 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5539 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5540 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5541 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5542 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5543 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5544 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5545 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5546 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5547 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5548 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5549 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5550 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5551 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5552 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5553 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5554 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5555 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5556 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5557 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5558 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5559 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5560 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5561 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5562 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5563 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5564  ip_source_and_port_range_check_add_del_reply)                          \
5565 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5566  ip_source_and_port_range_check_interface_add_del_reply)                \
5567 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5568 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5569 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5570 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5571 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5572 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5573 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5574 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5575 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5576 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5577 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5578 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5579 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5580 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5581 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5582 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5583 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5584 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5585 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5586 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5587 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5588 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5589 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5590 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5591 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5592 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5593
5594 #define foreach_standalone_reply_msg                                    \
5595 _(SW_INTERFACE_EVENT, sw_interface_event)
5596
5597 typedef struct
5598 {
5599   u8 *name;
5600   u32 value;
5601 } name_sort_t;
5602
5603 #define STR_VTR_OP_CASE(op)     \
5604     case L2_VTR_ ## op:         \
5605         return "" # op;
5606
5607 static const char *
5608 str_vtr_op (u32 vtr_op)
5609 {
5610   switch (vtr_op)
5611     {
5612       STR_VTR_OP_CASE (DISABLED);
5613       STR_VTR_OP_CASE (PUSH_1);
5614       STR_VTR_OP_CASE (PUSH_2);
5615       STR_VTR_OP_CASE (POP_1);
5616       STR_VTR_OP_CASE (POP_2);
5617       STR_VTR_OP_CASE (TRANSLATE_1_1);
5618       STR_VTR_OP_CASE (TRANSLATE_1_2);
5619       STR_VTR_OP_CASE (TRANSLATE_2_1);
5620       STR_VTR_OP_CASE (TRANSLATE_2_2);
5621     }
5622
5623   return "UNKNOWN";
5624 }
5625
5626 static int
5627 dump_sub_interface_table (vat_main_t * vam)
5628 {
5629   const sw_interface_subif_t *sub = NULL;
5630
5631   if (vam->json_output)
5632     {
5633       clib_warning
5634         ("JSON output supported only for VPE API calls and dump_stats_table");
5635       return -99;
5636     }
5637
5638   print (vam->ofp,
5639          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5640          "Interface", "sw_if_index",
5641          "sub id", "dot1ad", "tags", "outer id",
5642          "inner id", "exact", "default", "outer any", "inner any");
5643
5644   vec_foreach (sub, vam->sw_if_subif_table)
5645   {
5646     print (vam->ofp,
5647            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5648            sub->interface_name,
5649            sub->sw_if_index,
5650            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5651            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5652            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5653            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5654     if (sub->vtr_op != L2_VTR_DISABLED)
5655       {
5656         print (vam->ofp,
5657                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5658                "tag1: %d tag2: %d ]",
5659                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5660                sub->vtr_tag1, sub->vtr_tag2);
5661       }
5662   }
5663
5664   return 0;
5665 }
5666
5667 static int
5668 name_sort_cmp (void *a1, void *a2)
5669 {
5670   name_sort_t *n1 = a1;
5671   name_sort_t *n2 = a2;
5672
5673   return strcmp ((char *) n1->name, (char *) n2->name);
5674 }
5675
5676 static int
5677 dump_interface_table (vat_main_t * vam)
5678 {
5679   hash_pair_t *p;
5680   name_sort_t *nses = 0, *ns;
5681
5682   if (vam->json_output)
5683     {
5684       clib_warning
5685         ("JSON output supported only for VPE API calls and dump_stats_table");
5686       return -99;
5687     }
5688
5689   /* *INDENT-OFF* */
5690   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5691   ({
5692     vec_add2 (nses, ns, 1);
5693     ns->name = (u8 *)(p->key);
5694     ns->value = (u32) p->value[0];
5695   }));
5696   /* *INDENT-ON* */
5697
5698   vec_sort_with_function (nses, name_sort_cmp);
5699
5700   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5701   vec_foreach (ns, nses)
5702   {
5703     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5704   }
5705   vec_free (nses);
5706   return 0;
5707 }
5708
5709 static int
5710 dump_ip_table (vat_main_t * vam, int is_ipv6)
5711 {
5712   const ip_details_t *det = NULL;
5713   const ip_address_details_t *address = NULL;
5714   u32 i = ~0;
5715
5716   print (vam->ofp, "%-12s", "sw_if_index");
5717
5718   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5719   {
5720     i++;
5721     if (!det->present)
5722       {
5723         continue;
5724       }
5725     print (vam->ofp, "%-12d", i);
5726     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5727     if (!det->addr)
5728       {
5729         continue;
5730       }
5731     vec_foreach (address, det->addr)
5732     {
5733       print (vam->ofp,
5734              "            %-30U%-13d",
5735              is_ipv6 ? format_ip6_address : format_ip4_address,
5736              address->ip, address->prefix_length);
5737     }
5738   }
5739
5740   return 0;
5741 }
5742
5743 static int
5744 dump_ipv4_table (vat_main_t * vam)
5745 {
5746   if (vam->json_output)
5747     {
5748       clib_warning
5749         ("JSON output supported only for VPE API calls and dump_stats_table");
5750       return -99;
5751     }
5752
5753   return dump_ip_table (vam, 0);
5754 }
5755
5756 static int
5757 dump_ipv6_table (vat_main_t * vam)
5758 {
5759   if (vam->json_output)
5760     {
5761       clib_warning
5762         ("JSON output supported only for VPE API calls and dump_stats_table");
5763       return -99;
5764     }
5765
5766   return dump_ip_table (vam, 1);
5767 }
5768
5769 /*
5770  * Pass CLI buffers directly in the CLI_INBAND API message,
5771  * instead of an additional shared memory area.
5772  */
5773 static int
5774 exec_inband (vat_main_t * vam)
5775 {
5776   vl_api_cli_inband_t *mp;
5777   unformat_input_t *i = vam->input;
5778   int ret;
5779
5780   if (vec_len (i->buffer) == 0)
5781     return -1;
5782
5783   if (vam->exec_mode == 0 && unformat (i, "mode"))
5784     {
5785       vam->exec_mode = 1;
5786       return 0;
5787     }
5788   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5789     {
5790       vam->exec_mode = 0;
5791       return 0;
5792     }
5793
5794   /*
5795    * In order for the CLI command to work, it
5796    * must be a vector ending in \n, not a C-string ending
5797    * in \n\0.
5798    */
5799   u32 len = vec_len (vam->input->buffer);
5800   M2 (CLI_INBAND, mp, len);
5801   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5802
5803   S (mp);
5804   W (ret);
5805   /* json responses may or may not include a useful reply... */
5806   if (vec_len (vam->cmd_reply))
5807     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5808   return ret;
5809 }
5810
5811 int
5812 exec (vat_main_t * vam)
5813 {
5814   return exec_inband (vam);
5815 }
5816
5817 static int
5818 api_create_loopback (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_create_loopback_t *mp;
5822   vl_api_create_loopback_instance_t *mp_lbi;
5823   u8 mac_address[6];
5824   u8 mac_set = 0;
5825   u8 is_specified = 0;
5826   u32 user_instance = 0;
5827   int ret;
5828
5829   clib_memset (mac_address, 0, sizeof (mac_address));
5830
5831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5832     {
5833       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5834         mac_set = 1;
5835       if (unformat (i, "instance %d", &user_instance))
5836         is_specified = 1;
5837       else
5838         break;
5839     }
5840
5841   if (is_specified)
5842     {
5843       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5844       mp_lbi->is_specified = is_specified;
5845       if (is_specified)
5846         mp_lbi->user_instance = htonl (user_instance);
5847       if (mac_set)
5848         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5849       S (mp_lbi);
5850     }
5851   else
5852     {
5853       /* Construct the API message */
5854       M (CREATE_LOOPBACK, mp);
5855       if (mac_set)
5856         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5857       S (mp);
5858     }
5859
5860   W (ret);
5861   return ret;
5862 }
5863
5864 static int
5865 api_delete_loopback (vat_main_t * vam)
5866 {
5867   unformat_input_t *i = vam->input;
5868   vl_api_delete_loopback_t *mp;
5869   u32 sw_if_index = ~0;
5870   int ret;
5871
5872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5873     {
5874       if (unformat (i, "sw_if_index %d", &sw_if_index))
5875         ;
5876       else
5877         break;
5878     }
5879
5880   if (sw_if_index == ~0)
5881     {
5882       errmsg ("missing sw_if_index");
5883       return -99;
5884     }
5885
5886   /* Construct the API message */
5887   M (DELETE_LOOPBACK, mp);
5888   mp->sw_if_index = ntohl (sw_if_index);
5889
5890   S (mp);
5891   W (ret);
5892   return ret;
5893 }
5894
5895 static int
5896 api_want_interface_events (vat_main_t * vam)
5897 {
5898   unformat_input_t *i = vam->input;
5899   vl_api_want_interface_events_t *mp;
5900   int enable = -1;
5901   int ret;
5902
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "enable"))
5906         enable = 1;
5907       else if (unformat (i, "disable"))
5908         enable = 0;
5909       else
5910         break;
5911     }
5912
5913   if (enable == -1)
5914     {
5915       errmsg ("missing enable|disable");
5916       return -99;
5917     }
5918
5919   M (WANT_INTERFACE_EVENTS, mp);
5920   mp->enable_disable = enable;
5921
5922   vam->interface_event_display = enable;
5923
5924   S (mp);
5925   W (ret);
5926   return ret;
5927 }
5928
5929
5930 /* Note: non-static, called once to set up the initial intfc table */
5931 int
5932 api_sw_interface_dump (vat_main_t * vam)
5933 {
5934   vl_api_sw_interface_dump_t *mp;
5935   vl_api_control_ping_t *mp_ping;
5936   hash_pair_t *p;
5937   name_sort_t *nses = 0, *ns;
5938   sw_interface_subif_t *sub = NULL;
5939   int ret;
5940
5941   /* Toss the old name table */
5942   /* *INDENT-OFF* */
5943   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5944   ({
5945     vec_add2 (nses, ns, 1);
5946     ns->name = (u8 *)(p->key);
5947     ns->value = (u32) p->value[0];
5948   }));
5949   /* *INDENT-ON* */
5950
5951   hash_free (vam->sw_if_index_by_interface_name);
5952
5953   vec_foreach (ns, nses) vec_free (ns->name);
5954
5955   vec_free (nses);
5956
5957   vec_foreach (sub, vam->sw_if_subif_table)
5958   {
5959     vec_free (sub->interface_name);
5960   }
5961   vec_free (vam->sw_if_subif_table);
5962
5963   /* recreate the interface name hash table */
5964   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5965
5966   /*
5967    * Ask for all interface names. Otherwise, the epic catalog of
5968    * name filters becomes ridiculously long, and vat ends up needing
5969    * to be taught about new interface types.
5970    */
5971   M (SW_INTERFACE_DUMP, mp);
5972   S (mp);
5973
5974   /* Use a control ping for synchronization */
5975   MPING (CONTROL_PING, mp_ping);
5976   S (mp_ping);
5977
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static int
5983 api_sw_interface_set_flags (vat_main_t * vam)
5984 {
5985   unformat_input_t *i = vam->input;
5986   vl_api_sw_interface_set_flags_t *mp;
5987   u32 sw_if_index;
5988   u8 sw_if_index_set = 0;
5989   u8 admin_up = 0;
5990   int ret;
5991
5992   /* Parse args required to build the message */
5993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5994     {
5995       if (unformat (i, "admin-up"))
5996         admin_up = 1;
5997       else if (unformat (i, "admin-down"))
5998         admin_up = 0;
5999       else
6000         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6001         sw_if_index_set = 1;
6002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6003         sw_if_index_set = 1;
6004       else
6005         break;
6006     }
6007
6008   if (sw_if_index_set == 0)
6009     {
6010       errmsg ("missing interface name or sw_if_index");
6011       return -99;
6012     }
6013
6014   /* Construct the API message */
6015   M (SW_INTERFACE_SET_FLAGS, mp);
6016   mp->sw_if_index = ntohl (sw_if_index);
6017   mp->admin_up_down = admin_up;
6018
6019   /* send it... */
6020   S (mp);
6021
6022   /* Wait for a reply, return the good/bad news... */
6023   W (ret);
6024   return ret;
6025 }
6026
6027 static int
6028 api_sw_interface_set_rx_mode (vat_main_t * vam)
6029 {
6030   unformat_input_t *i = vam->input;
6031   vl_api_sw_interface_set_rx_mode_t *mp;
6032   u32 sw_if_index;
6033   u8 sw_if_index_set = 0;
6034   int ret;
6035   u8 queue_id_valid = 0;
6036   u32 queue_id;
6037   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6038
6039   /* Parse args required to build the message */
6040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6041     {
6042       if (unformat (i, "queue %d", &queue_id))
6043         queue_id_valid = 1;
6044       else if (unformat (i, "polling"))
6045         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6046       else if (unformat (i, "interrupt"))
6047         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6048       else if (unformat (i, "adaptive"))
6049         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6050       else
6051         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6052         sw_if_index_set = 1;
6053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6054         sw_if_index_set = 1;
6055       else
6056         break;
6057     }
6058
6059   if (sw_if_index_set == 0)
6060     {
6061       errmsg ("missing interface name or sw_if_index");
6062       return -99;
6063     }
6064   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6065     {
6066       errmsg ("missing rx-mode");
6067       return -99;
6068     }
6069
6070   /* Construct the API message */
6071   M (SW_INTERFACE_SET_RX_MODE, mp);
6072   mp->sw_if_index = ntohl (sw_if_index);
6073   mp->mode = mode;
6074   mp->queue_id_valid = queue_id_valid;
6075   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6076
6077   /* send it... */
6078   S (mp);
6079
6080   /* Wait for a reply, return the good/bad news... */
6081   W (ret);
6082   return ret;
6083 }
6084
6085 static int
6086 api_sw_interface_set_rx_placement (vat_main_t * vam)
6087 {
6088   unformat_input_t *i = vam->input;
6089   vl_api_sw_interface_set_rx_placement_t *mp;
6090   u32 sw_if_index;
6091   u8 sw_if_index_set = 0;
6092   int ret;
6093   u8 is_main = 0;
6094   u32 queue_id, thread_index;
6095
6096   /* Parse args required to build the message */
6097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6098     {
6099       if (unformat (i, "queue %d", &queue_id))
6100         ;
6101       else if (unformat (i, "main"))
6102         is_main = 1;
6103       else if (unformat (i, "worker %d", &thread_index))
6104         ;
6105       else
6106         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6107         sw_if_index_set = 1;
6108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6109         sw_if_index_set = 1;
6110       else
6111         break;
6112     }
6113
6114   if (sw_if_index_set == 0)
6115     {
6116       errmsg ("missing interface name or sw_if_index");
6117       return -99;
6118     }
6119
6120   if (is_main)
6121     thread_index = 0;
6122   /* Construct the API message */
6123   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6124   mp->sw_if_index = ntohl (sw_if_index);
6125   mp->worker_id = ntohl (thread_index);
6126   mp->queue_id = ntohl (queue_id);
6127   mp->is_main = is_main;
6128
6129   /* send it... */
6130   S (mp);
6131   /* Wait for a reply, return the good/bad news... */
6132   W (ret);
6133   return ret;
6134 }
6135
6136 static void vl_api_sw_interface_rx_placement_details_t_handler
6137   (vl_api_sw_interface_rx_placement_details_t * mp)
6138 {
6139   vat_main_t *vam = &vat_main;
6140   u32 worker_id = ntohl (mp->worker_id);
6141
6142   print (vam->ofp,
6143          "\n%-11d %-11s %-6d %-5d %-9s",
6144          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6145          worker_id, ntohl (mp->queue_id),
6146          (mp->mode ==
6147           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6148 }
6149
6150 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6151   (vl_api_sw_interface_rx_placement_details_t * mp)
6152 {
6153   vat_main_t *vam = &vat_main;
6154   vat_json_node_t *node = NULL;
6155
6156   if (VAT_JSON_ARRAY != vam->json_tree.type)
6157     {
6158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6159       vat_json_init_array (&vam->json_tree);
6160     }
6161   node = vat_json_array_add (&vam->json_tree);
6162
6163   vat_json_init_object (node);
6164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6165   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6166   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6167   vat_json_object_add_uint (node, "mode", mp->mode);
6168 }
6169
6170 static int
6171 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6172 {
6173   unformat_input_t *i = vam->input;
6174   vl_api_sw_interface_rx_placement_dump_t *mp;
6175   vl_api_control_ping_t *mp_ping;
6176   int ret;
6177   u32 sw_if_index;
6178   u8 sw_if_index_set = 0;
6179
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set++;
6184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185         sw_if_index_set++;
6186       else
6187         break;
6188     }
6189
6190   print (vam->ofp,
6191          "\n%-11s %-11s %-6s %-5s %-4s",
6192          "sw_if_index", "main/worker", "thread", "queue", "mode");
6193
6194   /* Dump Interface rx placement */
6195   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6196
6197   if (sw_if_index_set)
6198     mp->sw_if_index = htonl (sw_if_index);
6199   else
6200     mp->sw_if_index = ~0;
6201
6202   S (mp);
6203
6204   /* Use a control ping for synchronization */
6205   MPING (CONTROL_PING, mp_ping);
6206   S (mp_ping);
6207
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_sw_interface_clear_stats (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_sw_interface_clear_stats_t *mp;
6217   u32 sw_if_index;
6218   u8 sw_if_index_set = 0;
6219   int ret;
6220
6221   /* Parse args required to build the message */
6222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6223     {
6224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6225         sw_if_index_set = 1;
6226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6227         sw_if_index_set = 1;
6228       else
6229         break;
6230     }
6231
6232   /* Construct the API message */
6233   M (SW_INTERFACE_CLEAR_STATS, mp);
6234
6235   if (sw_if_index_set == 1)
6236     mp->sw_if_index = ntohl (sw_if_index);
6237   else
6238     mp->sw_if_index = ~0;
6239
6240   /* send it... */
6241   S (mp);
6242
6243   /* Wait for a reply, return the good/bad news... */
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_sw_interface_add_del_address (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_sw_interface_add_del_address_t *mp;
6253   u32 sw_if_index;
6254   u8 sw_if_index_set = 0;
6255   u8 is_add = 1, del_all = 0;
6256   u32 address_length = 0;
6257   u8 v4_address_set = 0;
6258   u8 v6_address_set = 0;
6259   ip4_address_t v4address;
6260   ip6_address_t v6address;
6261   int ret;
6262
6263   /* Parse args required to build the message */
6264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6265     {
6266       if (unformat (i, "del-all"))
6267         del_all = 1;
6268       else if (unformat (i, "del"))
6269         is_add = 0;
6270       else
6271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6272         sw_if_index_set = 1;
6273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6274         sw_if_index_set = 1;
6275       else if (unformat (i, "%U/%d",
6276                          unformat_ip4_address, &v4address, &address_length))
6277         v4_address_set = 1;
6278       else if (unformat (i, "%U/%d",
6279                          unformat_ip6_address, &v6address, &address_length))
6280         v6_address_set = 1;
6281       else
6282         break;
6283     }
6284
6285   if (sw_if_index_set == 0)
6286     {
6287       errmsg ("missing interface name or sw_if_index");
6288       return -99;
6289     }
6290   if (v4_address_set && v6_address_set)
6291     {
6292       errmsg ("both v4 and v6 addresses set");
6293       return -99;
6294     }
6295   if (!v4_address_set && !v6_address_set && !del_all)
6296     {
6297       errmsg ("no addresses set");
6298       return -99;
6299     }
6300
6301   /* Construct the API message */
6302   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6303
6304   mp->sw_if_index = ntohl (sw_if_index);
6305   mp->is_add = is_add;
6306   mp->del_all = del_all;
6307   if (v6_address_set)
6308     {
6309       mp->is_ipv6 = 1;
6310       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6311     }
6312   else
6313     {
6314       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6315     }
6316   mp->address_length = address_length;
6317
6318   /* send it... */
6319   S (mp);
6320
6321   /* Wait for a reply, return good/bad news  */
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static int
6327 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6328 {
6329   unformat_input_t *i = vam->input;
6330   vl_api_sw_interface_set_mpls_enable_t *mp;
6331   u32 sw_if_index;
6332   u8 sw_if_index_set = 0;
6333   u8 enable = 1;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "disable"))
6344         enable = 0;
6345       else if (unformat (i, "dis"))
6346         enable = 0;
6347       else
6348         break;
6349     }
6350
6351   if (sw_if_index_set == 0)
6352     {
6353       errmsg ("missing interface name or sw_if_index");
6354       return -99;
6355     }
6356
6357   /* Construct the API message */
6358   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6359
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   mp->enable = enable;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_sw_interface_set_table (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_sw_interface_set_table_t *mp;
6376   u32 sw_if_index, vrf_id = 0;
6377   u8 sw_if_index_set = 0;
6378   u8 is_ipv6 = 0;
6379   int ret;
6380
6381   /* Parse args required to build the message */
6382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6383     {
6384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6385         sw_if_index_set = 1;
6386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6387         sw_if_index_set = 1;
6388       else if (unformat (i, "vrf %d", &vrf_id))
6389         ;
6390       else if (unformat (i, "ipv6"))
6391         is_ipv6 = 1;
6392       else
6393         break;
6394     }
6395
6396   if (sw_if_index_set == 0)
6397     {
6398       errmsg ("missing interface name or sw_if_index");
6399       return -99;
6400     }
6401
6402   /* Construct the API message */
6403   M (SW_INTERFACE_SET_TABLE, mp);
6404
6405   mp->sw_if_index = ntohl (sw_if_index);
6406   mp->is_ipv6 = is_ipv6;
6407   mp->vrf_id = ntohl (vrf_id);
6408
6409   /* send it... */
6410   S (mp);
6411
6412   /* Wait for a reply... */
6413   W (ret);
6414   return ret;
6415 }
6416
6417 static void vl_api_sw_interface_get_table_reply_t_handler
6418   (vl_api_sw_interface_get_table_reply_t * mp)
6419 {
6420   vat_main_t *vam = &vat_main;
6421
6422   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6423
6424   vam->retval = ntohl (mp->retval);
6425   vam->result_ready = 1;
6426
6427 }
6428
6429 static void vl_api_sw_interface_get_table_reply_t_handler_json
6430   (vl_api_sw_interface_get_table_reply_t * mp)
6431 {
6432   vat_main_t *vam = &vat_main;
6433   vat_json_node_t node;
6434
6435   vat_json_init_object (&node);
6436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6437   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6438
6439   vat_json_print (vam->ofp, &node);
6440   vat_json_free (&node);
6441
6442   vam->retval = ntohl (mp->retval);
6443   vam->result_ready = 1;
6444 }
6445
6446 static int
6447 api_sw_interface_get_table (vat_main_t * vam)
6448 {
6449   unformat_input_t *i = vam->input;
6450   vl_api_sw_interface_get_table_t *mp;
6451   u32 sw_if_index;
6452   u8 sw_if_index_set = 0;
6453   u8 is_ipv6 = 0;
6454   int ret;
6455
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6459         sw_if_index_set = 1;
6460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6461         sw_if_index_set = 1;
6462       else if (unformat (i, "ipv6"))
6463         is_ipv6 = 1;
6464       else
6465         break;
6466     }
6467
6468   if (sw_if_index_set == 0)
6469     {
6470       errmsg ("missing interface name or sw_if_index");
6471       return -99;
6472     }
6473
6474   M (SW_INTERFACE_GET_TABLE, mp);
6475   mp->sw_if_index = htonl (sw_if_index);
6476   mp->is_ipv6 = is_ipv6;
6477
6478   S (mp);
6479   W (ret);
6480   return ret;
6481 }
6482
6483 static int
6484 api_sw_interface_set_vpath (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_sw_interface_set_vpath_t *mp;
6488   u32 sw_if_index = 0;
6489   u8 sw_if_index_set = 0;
6490   u8 is_enable = 0;
6491   int ret;
6492
6493   /* Parse args required to build the message */
6494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6495     {
6496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6497         sw_if_index_set = 1;
6498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6499         sw_if_index_set = 1;
6500       else if (unformat (i, "enable"))
6501         is_enable = 1;
6502       else if (unformat (i, "disable"))
6503         is_enable = 0;
6504       else
6505         break;
6506     }
6507
6508   if (sw_if_index_set == 0)
6509     {
6510       errmsg ("missing interface name or sw_if_index");
6511       return -99;
6512     }
6513
6514   /* Construct the API message */
6515   M (SW_INTERFACE_SET_VPATH, mp);
6516
6517   mp->sw_if_index = ntohl (sw_if_index);
6518   mp->enable = is_enable;
6519
6520   /* send it... */
6521   S (mp);
6522
6523   /* Wait for a reply... */
6524   W (ret);
6525   return ret;
6526 }
6527
6528 static int
6529 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6530 {
6531   unformat_input_t *i = vam->input;
6532   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6533   u32 sw_if_index = 0;
6534   u8 sw_if_index_set = 0;
6535   u8 is_enable = 1;
6536   u8 is_ipv6 = 0;
6537   int ret;
6538
6539   /* Parse args required to build the message */
6540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6541     {
6542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6543         sw_if_index_set = 1;
6544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "enable"))
6547         is_enable = 1;
6548       else if (unformat (i, "disable"))
6549         is_enable = 0;
6550       else if (unformat (i, "ip4"))
6551         is_ipv6 = 0;
6552       else if (unformat (i, "ip6"))
6553         is_ipv6 = 1;
6554       else
6555         break;
6556     }
6557
6558   if (sw_if_index_set == 0)
6559     {
6560       errmsg ("missing interface name or sw_if_index");
6561       return -99;
6562     }
6563
6564   /* Construct the API message */
6565   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6566
6567   mp->sw_if_index = ntohl (sw_if_index);
6568   mp->enable = is_enable;
6569   mp->is_ipv6 = is_ipv6;
6570
6571   /* send it... */
6572   S (mp);
6573
6574   /* Wait for a reply... */
6575   W (ret);
6576   return ret;
6577 }
6578
6579 static int
6580 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6581 {
6582   unformat_input_t *i = vam->input;
6583   vl_api_sw_interface_set_geneve_bypass_t *mp;
6584   u32 sw_if_index = 0;
6585   u8 sw_if_index_set = 0;
6586   u8 is_enable = 1;
6587   u8 is_ipv6 = 0;
6588   int ret;
6589
6590   /* Parse args required to build the message */
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "enable"))
6598         is_enable = 1;
6599       else if (unformat (i, "disable"))
6600         is_enable = 0;
6601       else if (unformat (i, "ip4"))
6602         is_ipv6 = 0;
6603       else if (unformat (i, "ip6"))
6604         is_ipv6 = 1;
6605       else
6606         break;
6607     }
6608
6609   if (sw_if_index_set == 0)
6610     {
6611       errmsg ("missing interface name or sw_if_index");
6612       return -99;
6613     }
6614
6615   /* Construct the API message */
6616   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6617
6618   mp->sw_if_index = ntohl (sw_if_index);
6619   mp->enable = is_enable;
6620   mp->is_ipv6 = is_ipv6;
6621
6622   /* send it... */
6623   S (mp);
6624
6625   /* Wait for a reply... */
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_sw_interface_set_l2_xconnect_t *mp;
6635   u32 rx_sw_if_index;
6636   u8 rx_sw_if_index_set = 0;
6637   u32 tx_sw_if_index;
6638   u8 tx_sw_if_index_set = 0;
6639   u8 enable = 1;
6640   int ret;
6641
6642   /* Parse args required to build the message */
6643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644     {
6645       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6646         rx_sw_if_index_set = 1;
6647       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6648         tx_sw_if_index_set = 1;
6649       else if (unformat (i, "rx"))
6650         {
6651           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6652             {
6653               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6654                             &rx_sw_if_index))
6655                 rx_sw_if_index_set = 1;
6656             }
6657           else
6658             break;
6659         }
6660       else if (unformat (i, "tx"))
6661         {
6662           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663             {
6664               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6665                             &tx_sw_if_index))
6666                 tx_sw_if_index_set = 1;
6667             }
6668           else
6669             break;
6670         }
6671       else if (unformat (i, "enable"))
6672         enable = 1;
6673       else if (unformat (i, "disable"))
6674         enable = 0;
6675       else
6676         break;
6677     }
6678
6679   if (rx_sw_if_index_set == 0)
6680     {
6681       errmsg ("missing rx interface name or rx_sw_if_index");
6682       return -99;
6683     }
6684
6685   if (enable && (tx_sw_if_index_set == 0))
6686     {
6687       errmsg ("missing tx interface name or tx_sw_if_index");
6688       return -99;
6689     }
6690
6691   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6692
6693   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6694   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6695   mp->enable = enable;
6696
6697   S (mp);
6698   W (ret);
6699   return ret;
6700 }
6701
6702 static int
6703 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6704 {
6705   unformat_input_t *i = vam->input;
6706   vl_api_sw_interface_set_l2_bridge_t *mp;
6707   vl_api_l2_port_type_t port_type;
6708   u32 rx_sw_if_index;
6709   u8 rx_sw_if_index_set = 0;
6710   u32 bd_id;
6711   u8 bd_id_set = 0;
6712   u32 shg = 0;
6713   u8 enable = 1;
6714   int ret;
6715
6716   port_type = L2_API_PORT_TYPE_NORMAL;
6717
6718   /* Parse args required to build the message */
6719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6720     {
6721       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6722         rx_sw_if_index_set = 1;
6723       else if (unformat (i, "bd_id %d", &bd_id))
6724         bd_id_set = 1;
6725       else
6726         if (unformat
6727             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6728         rx_sw_if_index_set = 1;
6729       else if (unformat (i, "shg %d", &shg))
6730         ;
6731       else if (unformat (i, "bvi"))
6732         port_type = L2_API_PORT_TYPE_BVI;
6733       else if (unformat (i, "uu-fwd"))
6734         port_type = L2_API_PORT_TYPE_UU_FWD;
6735       else if (unformat (i, "enable"))
6736         enable = 1;
6737       else if (unformat (i, "disable"))
6738         enable = 0;
6739       else
6740         break;
6741     }
6742
6743   if (rx_sw_if_index_set == 0)
6744     {
6745       errmsg ("missing rx interface name or sw_if_index");
6746       return -99;
6747     }
6748
6749   if (enable && (bd_id_set == 0))
6750     {
6751       errmsg ("missing bridge domain");
6752       return -99;
6753     }
6754
6755   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6756
6757   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6758   mp->bd_id = ntohl (bd_id);
6759   mp->shg = (u8) shg;
6760   mp->port_type = ntohl (port_type);
6761   mp->enable = enable;
6762
6763   S (mp);
6764   W (ret);
6765   return ret;
6766 }
6767
6768 static int
6769 api_bridge_domain_dump (vat_main_t * vam)
6770 {
6771   unformat_input_t *i = vam->input;
6772   vl_api_bridge_domain_dump_t *mp;
6773   vl_api_control_ping_t *mp_ping;
6774   u32 bd_id = ~0;
6775   int ret;
6776
6777   /* Parse args required to build the message */
6778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6779     {
6780       if (unformat (i, "bd_id %d", &bd_id))
6781         ;
6782       else
6783         break;
6784     }
6785
6786   M (BRIDGE_DOMAIN_DUMP, mp);
6787   mp->bd_id = ntohl (bd_id);
6788   S (mp);
6789
6790   /* Use a control ping for synchronization */
6791   MPING (CONTROL_PING, mp_ping);
6792   S (mp_ping);
6793
6794   W (ret);
6795   return ret;
6796 }
6797
6798 static int
6799 api_bridge_domain_add_del (vat_main_t * vam)
6800 {
6801   unformat_input_t *i = vam->input;
6802   vl_api_bridge_domain_add_del_t *mp;
6803   u32 bd_id = ~0;
6804   u8 is_add = 1;
6805   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6806   u8 *bd_tag = NULL;
6807   u32 mac_age = 0;
6808   int ret;
6809
6810   /* Parse args required to build the message */
6811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6812     {
6813       if (unformat (i, "bd_id %d", &bd_id))
6814         ;
6815       else if (unformat (i, "flood %d", &flood))
6816         ;
6817       else if (unformat (i, "uu-flood %d", &uu_flood))
6818         ;
6819       else if (unformat (i, "forward %d", &forward))
6820         ;
6821       else if (unformat (i, "learn %d", &learn))
6822         ;
6823       else if (unformat (i, "arp-term %d", &arp_term))
6824         ;
6825       else if (unformat (i, "mac-age %d", &mac_age))
6826         ;
6827       else if (unformat (i, "bd-tag %s", &bd_tag))
6828         ;
6829       else if (unformat (i, "del"))
6830         {
6831           is_add = 0;
6832           flood = uu_flood = forward = learn = 0;
6833         }
6834       else
6835         break;
6836     }
6837
6838   if (bd_id == ~0)
6839     {
6840       errmsg ("missing bridge domain");
6841       ret = -99;
6842       goto done;
6843     }
6844
6845   if (mac_age > 255)
6846     {
6847       errmsg ("mac age must be less than 256 ");
6848       ret = -99;
6849       goto done;
6850     }
6851
6852   if ((bd_tag) && (vec_len (bd_tag) > 63))
6853     {
6854       errmsg ("bd-tag cannot be longer than 63");
6855       ret = -99;
6856       goto done;
6857     }
6858
6859   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6860
6861   mp->bd_id = ntohl (bd_id);
6862   mp->flood = flood;
6863   mp->uu_flood = uu_flood;
6864   mp->forward = forward;
6865   mp->learn = learn;
6866   mp->arp_term = arp_term;
6867   mp->is_add = is_add;
6868   mp->mac_age = (u8) mac_age;
6869   if (bd_tag)
6870     {
6871       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6872       mp->bd_tag[vec_len (bd_tag)] = 0;
6873     }
6874   S (mp);
6875   W (ret);
6876
6877 done:
6878   vec_free (bd_tag);
6879   return ret;
6880 }
6881
6882 static int
6883 api_l2fib_flush_bd (vat_main_t * vam)
6884 {
6885   unformat_input_t *i = vam->input;
6886   vl_api_l2fib_flush_bd_t *mp;
6887   u32 bd_id = ~0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "bd_id %d", &bd_id));
6894       else
6895         break;
6896     }
6897
6898   if (bd_id == ~0)
6899     {
6900       errmsg ("missing bridge domain");
6901       return -99;
6902     }
6903
6904   M (L2FIB_FLUSH_BD, mp);
6905
6906   mp->bd_id = htonl (bd_id);
6907
6908   S (mp);
6909   W (ret);
6910   return ret;
6911 }
6912
6913 static int
6914 api_l2fib_flush_int (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_l2fib_flush_int_t *mp;
6918   u32 sw_if_index = ~0;
6919   int ret;
6920
6921   /* Parse args required to build the message */
6922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6923     {
6924       if (unformat (i, "sw_if_index %d", &sw_if_index));
6925       else
6926         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6927       else
6928         break;
6929     }
6930
6931   if (sw_if_index == ~0)
6932     {
6933       errmsg ("missing interface name or sw_if_index");
6934       return -99;
6935     }
6936
6937   M (L2FIB_FLUSH_INT, mp);
6938
6939   mp->sw_if_index = ntohl (sw_if_index);
6940
6941   S (mp);
6942   W (ret);
6943   return ret;
6944 }
6945
6946 static int
6947 api_l2fib_add_del (vat_main_t * vam)
6948 {
6949   unformat_input_t *i = vam->input;
6950   vl_api_l2fib_add_del_t *mp;
6951   f64 timeout;
6952   u8 mac[6] = { 0 };
6953   u8 mac_set = 0;
6954   u32 bd_id;
6955   u8 bd_id_set = 0;
6956   u32 sw_if_index = 0;
6957   u8 sw_if_index_set = 0;
6958   u8 is_add = 1;
6959   u8 static_mac = 0;
6960   u8 filter_mac = 0;
6961   u8 bvi_mac = 0;
6962   int count = 1;
6963   f64 before = 0;
6964   int j;
6965
6966   /* Parse args required to build the message */
6967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968     {
6969       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6970         mac_set = 1;
6971       else if (unformat (i, "bd_id %d", &bd_id))
6972         bd_id_set = 1;
6973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6974         sw_if_index_set = 1;
6975       else if (unformat (i, "sw_if"))
6976         {
6977           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978             {
6979               if (unformat
6980                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6981                 sw_if_index_set = 1;
6982             }
6983           else
6984             break;
6985         }
6986       else if (unformat (i, "static"))
6987         static_mac = 1;
6988       else if (unformat (i, "filter"))
6989         {
6990           filter_mac = 1;
6991           static_mac = 1;
6992         }
6993       else if (unformat (i, "bvi"))
6994         {
6995           bvi_mac = 1;
6996           static_mac = 1;
6997         }
6998       else if (unformat (i, "del"))
6999         is_add = 0;
7000       else if (unformat (i, "count %d", &count))
7001         ;
7002       else
7003         break;
7004     }
7005
7006   if (mac_set == 0)
7007     {
7008       errmsg ("missing mac address");
7009       return -99;
7010     }
7011
7012   if (bd_id_set == 0)
7013     {
7014       errmsg ("missing bridge domain");
7015       return -99;
7016     }
7017
7018   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7019     {
7020       errmsg ("missing interface name or sw_if_index");
7021       return -99;
7022     }
7023
7024   if (count > 1)
7025     {
7026       /* Turn on async mode */
7027       vam->async_mode = 1;
7028       vam->async_errors = 0;
7029       before = vat_time_now (vam);
7030     }
7031
7032   for (j = 0; j < count; j++)
7033     {
7034       M (L2FIB_ADD_DEL, mp);
7035
7036       clib_memcpy (mp->mac, mac, 6);
7037       mp->bd_id = ntohl (bd_id);
7038       mp->is_add = is_add;
7039       mp->sw_if_index = ntohl (sw_if_index);
7040
7041       if (is_add)
7042         {
7043           mp->static_mac = static_mac;
7044           mp->filter_mac = filter_mac;
7045           mp->bvi_mac = bvi_mac;
7046         }
7047       increment_mac_address (mac);
7048       /* send it... */
7049       S (mp);
7050     }
7051
7052   if (count > 1)
7053     {
7054       vl_api_control_ping_t *mp_ping;
7055       f64 after;
7056
7057       /* Shut off async mode */
7058       vam->async_mode = 0;
7059
7060       MPING (CONTROL_PING, mp_ping);
7061       S (mp_ping);
7062
7063       timeout = vat_time_now (vam) + 1.0;
7064       while (vat_time_now (vam) < timeout)
7065         if (vam->result_ready == 1)
7066           goto out;
7067       vam->retval = -99;
7068
7069     out:
7070       if (vam->retval == -99)
7071         errmsg ("timeout");
7072
7073       if (vam->async_errors > 0)
7074         {
7075           errmsg ("%d asynchronous errors", vam->async_errors);
7076           vam->retval = -98;
7077         }
7078       vam->async_errors = 0;
7079       after = vat_time_now (vam);
7080
7081       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7082              count, after - before, count / (after - before));
7083     }
7084   else
7085     {
7086       int ret;
7087
7088       /* Wait for a reply... */
7089       W (ret);
7090       return ret;
7091     }
7092   /* Return the good/bad news */
7093   return (vam->retval);
7094 }
7095
7096 static int
7097 api_bridge_domain_set_mac_age (vat_main_t * vam)
7098 {
7099   unformat_input_t *i = vam->input;
7100   vl_api_bridge_domain_set_mac_age_t *mp;
7101   u32 bd_id = ~0;
7102   u32 mac_age = 0;
7103   int ret;
7104
7105   /* Parse args required to build the message */
7106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7107     {
7108       if (unformat (i, "bd_id %d", &bd_id));
7109       else if (unformat (i, "mac-age %d", &mac_age));
7110       else
7111         break;
7112     }
7113
7114   if (bd_id == ~0)
7115     {
7116       errmsg ("missing bridge domain");
7117       return -99;
7118     }
7119
7120   if (mac_age > 255)
7121     {
7122       errmsg ("mac age must be less than 256 ");
7123       return -99;
7124     }
7125
7126   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7127
7128   mp->bd_id = htonl (bd_id);
7129   mp->mac_age = (u8) mac_age;
7130
7131   S (mp);
7132   W (ret);
7133   return ret;
7134 }
7135
7136 static int
7137 api_l2_flags (vat_main_t * vam)
7138 {
7139   unformat_input_t *i = vam->input;
7140   vl_api_l2_flags_t *mp;
7141   u32 sw_if_index;
7142   u32 flags = 0;
7143   u8 sw_if_index_set = 0;
7144   u8 is_set = 0;
7145   int ret;
7146
7147   /* Parse args required to build the message */
7148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149     {
7150       if (unformat (i, "sw_if_index %d", &sw_if_index))
7151         sw_if_index_set = 1;
7152       else if (unformat (i, "sw_if"))
7153         {
7154           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155             {
7156               if (unformat
7157                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158                 sw_if_index_set = 1;
7159             }
7160           else
7161             break;
7162         }
7163       else if (unformat (i, "learn"))
7164         flags |= L2_LEARN;
7165       else if (unformat (i, "forward"))
7166         flags |= L2_FWD;
7167       else if (unformat (i, "flood"))
7168         flags |= L2_FLOOD;
7169       else if (unformat (i, "uu-flood"))
7170         flags |= L2_UU_FLOOD;
7171       else if (unformat (i, "arp-term"))
7172         flags |= L2_ARP_TERM;
7173       else if (unformat (i, "off"))
7174         is_set = 0;
7175       else if (unformat (i, "disable"))
7176         is_set = 0;
7177       else
7178         break;
7179     }
7180
7181   if (sw_if_index_set == 0)
7182     {
7183       errmsg ("missing interface name or sw_if_index");
7184       return -99;
7185     }
7186
7187   M (L2_FLAGS, mp);
7188
7189   mp->sw_if_index = ntohl (sw_if_index);
7190   mp->feature_bitmap = ntohl (flags);
7191   mp->is_set = is_set;
7192
7193   S (mp);
7194   W (ret);
7195   return ret;
7196 }
7197
7198 static int
7199 api_bridge_flags (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_bridge_flags_t *mp;
7203   u32 bd_id;
7204   u8 bd_id_set = 0;
7205   u8 is_set = 1;
7206   bd_flags_t flags = 0;
7207   int ret;
7208
7209   /* Parse args required to build the message */
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "bd_id %d", &bd_id))
7213         bd_id_set = 1;
7214       else if (unformat (i, "learn"))
7215         flags |= BRIDGE_API_FLAG_LEARN;
7216       else if (unformat (i, "forward"))
7217         flags |= BRIDGE_API_FLAG_FWD;
7218       else if (unformat (i, "flood"))
7219         flags |= BRIDGE_API_FLAG_FLOOD;
7220       else if (unformat (i, "uu-flood"))
7221         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7222       else if (unformat (i, "arp-term"))
7223         flags |= BRIDGE_API_FLAG_ARP_TERM;
7224       else if (unformat (i, "off"))
7225         is_set = 0;
7226       else if (unformat (i, "disable"))
7227         is_set = 0;
7228       else
7229         break;
7230     }
7231
7232   if (bd_id_set == 0)
7233     {
7234       errmsg ("missing bridge domain");
7235       return -99;
7236     }
7237
7238   M (BRIDGE_FLAGS, mp);
7239
7240   mp->bd_id = ntohl (bd_id);
7241   mp->flags = ntohl (flags);
7242   mp->is_set = is_set;
7243
7244   S (mp);
7245   W (ret);
7246   return ret;
7247 }
7248
7249 static int
7250 api_bd_ip_mac_add_del (vat_main_t * vam)
7251 {
7252   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7253   vl_api_mac_address_t mac = { 0 };
7254   unformat_input_t *i = vam->input;
7255   vl_api_bd_ip_mac_add_del_t *mp;
7256   u32 bd_id;
7257   u8 is_add = 1;
7258   u8 bd_id_set = 0;
7259   u8 ip_set = 0;
7260   u8 mac_set = 0;
7261   int ret;
7262
7263
7264   /* Parse args required to build the message */
7265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7266     {
7267       if (unformat (i, "bd_id %d", &bd_id))
7268         {
7269           bd_id_set++;
7270         }
7271       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7272         {
7273           ip_set++;
7274         }
7275       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7276         {
7277           mac_set++;
7278         }
7279       else if (unformat (i, "del"))
7280         is_add = 0;
7281       else
7282         break;
7283     }
7284
7285   if (bd_id_set == 0)
7286     {
7287       errmsg ("missing bridge domain");
7288       return -99;
7289     }
7290   else if (ip_set == 0)
7291     {
7292       errmsg ("missing IP address");
7293       return -99;
7294     }
7295   else if (mac_set == 0)
7296     {
7297       errmsg ("missing MAC address");
7298       return -99;
7299     }
7300
7301   M (BD_IP_MAC_ADD_DEL, mp);
7302
7303   mp->bd_id = ntohl (bd_id);
7304   mp->is_add = is_add;
7305
7306   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7307   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7308
7309   S (mp);
7310   W (ret);
7311   return ret;
7312 }
7313
7314 static int
7315 api_bd_ip_mac_flush (vat_main_t * vam)
7316 {
7317   unformat_input_t *i = vam->input;
7318   vl_api_bd_ip_mac_flush_t *mp;
7319   u32 bd_id;
7320   u8 bd_id_set = 0;
7321   int ret;
7322
7323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7324     {
7325       if (unformat (i, "bd_id %d", &bd_id))
7326         {
7327           bd_id_set++;
7328         }
7329       else
7330         break;
7331     }
7332
7333   if (bd_id_set == 0)
7334     {
7335       errmsg ("missing bridge domain");
7336       return -99;
7337     }
7338
7339   M (BD_IP_MAC_FLUSH, mp);
7340
7341   mp->bd_id = ntohl (bd_id);
7342
7343   S (mp);
7344   W (ret);
7345   return ret;
7346 }
7347
7348 static void vl_api_bd_ip_mac_details_t_handler
7349   (vl_api_bd_ip_mac_details_t * mp)
7350 {
7351   vat_main_t *vam = &vat_main;
7352   u8 *ip = 0;
7353
7354   if (!mp->is_ipv6)
7355     ip =
7356       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7357   else
7358     ip =
7359       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7360
7361   print (vam->ofp,
7362          "\n%-5d %-7s %-20U %-30s",
7363          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7364          format_ethernet_address, mp->mac_address, ip);
7365
7366   vec_free (ip);
7367 }
7368
7369 static void vl_api_bd_ip_mac_details_t_handler_json
7370   (vl_api_bd_ip_mac_details_t * mp)
7371 {
7372   vat_main_t *vam = &vat_main;
7373   vat_json_node_t *node = NULL;
7374
7375   if (VAT_JSON_ARRAY != vam->json_tree.type)
7376     {
7377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7378       vat_json_init_array (&vam->json_tree);
7379     }
7380   node = vat_json_array_add (&vam->json_tree);
7381
7382   vat_json_init_object (node);
7383   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7384   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7385   vat_json_object_add_string_copy (node, "mac_address",
7386                                    format (0, "%U", format_ethernet_address,
7387                                            &mp->mac_address));
7388   u8 *ip = 0;
7389
7390   if (!mp->is_ipv6)
7391     ip =
7392       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7393   else
7394     ip =
7395       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7396   vat_json_object_add_string_copy (node, "ip_address", ip);
7397   vec_free (ip);
7398 }
7399
7400 static int
7401 api_bd_ip_mac_dump (vat_main_t * vam)
7402 {
7403   unformat_input_t *i = vam->input;
7404   vl_api_bd_ip_mac_dump_t *mp;
7405   vl_api_control_ping_t *mp_ping;
7406   int ret;
7407   u32 bd_id;
7408   u8 bd_id_set = 0;
7409
7410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7411     {
7412       if (unformat (i, "bd_id %d", &bd_id))
7413         {
7414           bd_id_set++;
7415         }
7416       else
7417         break;
7418     }
7419
7420   print (vam->ofp,
7421          "\n%-5s %-7s %-20s %-30s",
7422          "bd_id", "is_ipv6", "mac_address", "ip_address");
7423
7424   /* Dump Bridge Domain Ip to Mac entries */
7425   M (BD_IP_MAC_DUMP, mp);
7426
7427   if (bd_id_set)
7428     mp->bd_id = htonl (bd_id);
7429   else
7430     mp->bd_id = ~0;
7431
7432   S (mp);
7433
7434   /* Use a control ping for synchronization */
7435   MPING (CONTROL_PING, mp_ping);
7436   S (mp_ping);
7437
7438   W (ret);
7439   return ret;
7440 }
7441
7442 static int
7443 api_tap_create_v2 (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_tap_create_v2_t *mp;
7447   u8 mac_address[6];
7448   u8 random_mac = 1;
7449   u32 id = ~0;
7450   u8 *host_if_name = 0;
7451   u8 *host_ns = 0;
7452   u8 host_mac_addr[6];
7453   u8 host_mac_addr_set = 0;
7454   u8 *host_bridge = 0;
7455   ip4_address_t host_ip4_addr;
7456   ip4_address_t host_ip4_gw;
7457   u8 host_ip4_gw_set = 0;
7458   u32 host_ip4_prefix_len = 0;
7459   ip6_address_t host_ip6_addr;
7460   ip6_address_t host_ip6_gw;
7461   u8 host_ip6_gw_set = 0;
7462   u32 host_ip6_prefix_len = 0;
7463   int ret;
7464   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7465
7466   clib_memset (mac_address, 0, sizeof (mac_address));
7467
7468   /* Parse args required to build the message */
7469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7470     {
7471       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7472         {
7473           random_mac = 0;
7474         }
7475       else if (unformat (i, "id %u", &id))
7476         ;
7477       else if (unformat (i, "host-if-name %s", &host_if_name))
7478         ;
7479       else if (unformat (i, "host-ns %s", &host_ns))
7480         ;
7481       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7482                          host_mac_addr))
7483         host_mac_addr_set = 1;
7484       else if (unformat (i, "host-bridge %s", &host_bridge))
7485         ;
7486       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7487                          &host_ip4_addr, &host_ip4_prefix_len))
7488         ;
7489       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7490                          &host_ip6_addr, &host_ip6_prefix_len))
7491         ;
7492       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7493                          &host_ip4_gw))
7494         host_ip4_gw_set = 1;
7495       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7496                          &host_ip6_gw))
7497         host_ip6_gw_set = 1;
7498       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7499         ;
7500       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7501         ;
7502       else
7503         break;
7504     }
7505
7506   if (vec_len (host_if_name) > 63)
7507     {
7508       errmsg ("tap name too long. ");
7509       return -99;
7510     }
7511   if (vec_len (host_ns) > 63)
7512     {
7513       errmsg ("host name space too long. ");
7514       return -99;
7515     }
7516   if (vec_len (host_bridge) > 63)
7517     {
7518       errmsg ("host bridge name too long. ");
7519       return -99;
7520     }
7521   if (host_ip4_prefix_len > 32)
7522     {
7523       errmsg ("host ip4 prefix length not valid. ");
7524       return -99;
7525     }
7526   if (host_ip6_prefix_len > 128)
7527     {
7528       errmsg ("host ip6 prefix length not valid. ");
7529       return -99;
7530     }
7531   if (!is_pow2 (rx_ring_sz))
7532     {
7533       errmsg ("rx ring size must be power of 2. ");
7534       return -99;
7535     }
7536   if (rx_ring_sz > 32768)
7537     {
7538       errmsg ("rx ring size must be 32768 or lower. ");
7539       return -99;
7540     }
7541   if (!is_pow2 (tx_ring_sz))
7542     {
7543       errmsg ("tx ring size must be power of 2. ");
7544       return -99;
7545     }
7546   if (tx_ring_sz > 32768)
7547     {
7548       errmsg ("tx ring size must be 32768 or lower. ");
7549       return -99;
7550     }
7551
7552   /* Construct the API message */
7553   M (TAP_CREATE_V2, mp);
7554
7555   mp->use_random_mac = random_mac;
7556
7557   mp->id = ntohl (id);
7558   mp->host_namespace_set = host_ns != 0;
7559   mp->host_bridge_set = host_bridge != 0;
7560   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7561   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7562   mp->rx_ring_sz = ntohs (rx_ring_sz);
7563   mp->tx_ring_sz = ntohs (tx_ring_sz);
7564
7565   if (random_mac == 0)
7566     clib_memcpy (mp->mac_address, mac_address, 6);
7567   if (host_mac_addr_set)
7568     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7569   if (host_if_name)
7570     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7571   if (host_ns)
7572     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7573   if (host_bridge)
7574     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7575   if (host_ip4_prefix_len)
7576     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7577   if (host_ip6_prefix_len)
7578     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7579   if (host_ip4_gw_set)
7580     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7581   if (host_ip6_gw_set)
7582     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7583
7584   vec_free (host_ns);
7585   vec_free (host_if_name);
7586   vec_free (host_bridge);
7587
7588   /* send it... */
7589   S (mp);
7590
7591   /* Wait for a reply... */
7592   W (ret);
7593   return ret;
7594 }
7595
7596 static int
7597 api_tap_delete_v2 (vat_main_t * vam)
7598 {
7599   unformat_input_t *i = vam->input;
7600   vl_api_tap_delete_v2_t *mp;
7601   u32 sw_if_index = ~0;
7602   u8 sw_if_index_set = 0;
7603   int ret;
7604
7605   /* Parse args required to build the message */
7606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7607     {
7608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7609         sw_if_index_set = 1;
7610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7611         sw_if_index_set = 1;
7612       else
7613         break;
7614     }
7615
7616   if (sw_if_index_set == 0)
7617     {
7618       errmsg ("missing vpp interface name. ");
7619       return -99;
7620     }
7621
7622   /* Construct the API message */
7623   M (TAP_DELETE_V2, mp);
7624
7625   mp->sw_if_index = ntohl (sw_if_index);
7626
7627   /* send it... */
7628   S (mp);
7629
7630   /* Wait for a reply... */
7631   W (ret);
7632   return ret;
7633 }
7634
7635 uword
7636 unformat_pci_addr (unformat_input_t * input, va_list * args)
7637 {
7638   struct pci_addr_t
7639   {
7640     u16 domain;
7641     u8 bus;
7642     u8 slot:5;
7643     u8 function:3;
7644   } *addr;
7645   addr = va_arg (*args, struct pci_addr_t *);
7646   u32 x[4];
7647
7648   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7649     return 0;
7650
7651   addr->domain = x[0];
7652   addr->bus = x[1];
7653   addr->slot = x[2];
7654   addr->function = x[3];
7655
7656   return 1;
7657 }
7658
7659 static int
7660 api_virtio_pci_create (vat_main_t * vam)
7661 {
7662   unformat_input_t *i = vam->input;
7663   vl_api_virtio_pci_create_t *mp;
7664   u8 mac_address[6];
7665   u8 random_mac = 1;
7666   u8 gso_enabled = 0;
7667   u32 pci_addr = 0;
7668   u64 features = (u64) ~ (0ULL);
7669   int ret;
7670
7671   clib_memset (mac_address, 0, sizeof (mac_address));
7672
7673   /* Parse args required to build the message */
7674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675     {
7676       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7677         {
7678           random_mac = 0;
7679         }
7680       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7681         ;
7682       else if (unformat (i, "features 0x%llx", &features))
7683         ;
7684       else if (unformat (i, "gso-enabled"))
7685         gso_enabled = 1;
7686       else
7687         break;
7688     }
7689
7690   if (pci_addr == 0)
7691     {
7692       errmsg ("pci address must be non zero. ");
7693       return -99;
7694     }
7695
7696   /* Construct the API message */
7697   M (VIRTIO_PCI_CREATE, mp);
7698
7699   mp->use_random_mac = random_mac;
7700
7701   mp->pci_addr = htonl (pci_addr);
7702   mp->features = clib_host_to_net_u64 (features);
7703   mp->gso_enabled = gso_enabled;
7704
7705   if (random_mac == 0)
7706     clib_memcpy (mp->mac_address, mac_address, 6);
7707
7708   /* send it... */
7709   S (mp);
7710
7711   /* Wait for a reply... */
7712   W (ret);
7713   return ret;
7714 }
7715
7716 static int
7717 api_virtio_pci_delete (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_virtio_pci_delete_t *mp;
7721   u32 sw_if_index = ~0;
7722   u8 sw_if_index_set = 0;
7723   int ret;
7724
7725   /* Parse args required to build the message */
7726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7727     {
7728       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7729         sw_if_index_set = 1;
7730       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7731         sw_if_index_set = 1;
7732       else
7733         break;
7734     }
7735
7736   if (sw_if_index_set == 0)
7737     {
7738       errmsg ("missing vpp interface name. ");
7739       return -99;
7740     }
7741
7742   /* Construct the API message */
7743   M (VIRTIO_PCI_DELETE, mp);
7744
7745   mp->sw_if_index = htonl (sw_if_index);
7746
7747   /* send it... */
7748   S (mp);
7749
7750   /* Wait for a reply... */
7751   W (ret);
7752   return ret;
7753 }
7754
7755 static int
7756 api_bond_create (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_bond_create_t *mp;
7760   u8 mac_address[6];
7761   u8 custom_mac = 0;
7762   int ret;
7763   u8 mode;
7764   u8 lb;
7765   u8 mode_is_set = 0;
7766   u32 id = ~0;
7767
7768   clib_memset (mac_address, 0, sizeof (mac_address));
7769   lb = BOND_LB_L2;
7770
7771   /* Parse args required to build the message */
7772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7773     {
7774       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7775         mode_is_set = 1;
7776       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7777                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7778         ;
7779       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7780                          mac_address))
7781         custom_mac = 1;
7782       else if (unformat (i, "id %u", &id))
7783         ;
7784       else
7785         break;
7786     }
7787
7788   if (mode_is_set == 0)
7789     {
7790       errmsg ("Missing bond mode. ");
7791       return -99;
7792     }
7793
7794   /* Construct the API message */
7795   M (BOND_CREATE, mp);
7796
7797   mp->use_custom_mac = custom_mac;
7798
7799   mp->mode = mode;
7800   mp->lb = lb;
7801   mp->id = htonl (id);
7802
7803   if (custom_mac)
7804     clib_memcpy (mp->mac_address, mac_address, 6);
7805
7806   /* send it... */
7807   S (mp);
7808
7809   /* Wait for a reply... */
7810   W (ret);
7811   return ret;
7812 }
7813
7814 static int
7815 api_bond_delete (vat_main_t * vam)
7816 {
7817   unformat_input_t *i = vam->input;
7818   vl_api_bond_delete_t *mp;
7819   u32 sw_if_index = ~0;
7820   u8 sw_if_index_set = 0;
7821   int ret;
7822
7823   /* Parse args required to build the message */
7824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7825     {
7826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7827         sw_if_index_set = 1;
7828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7829         sw_if_index_set = 1;
7830       else
7831         break;
7832     }
7833
7834   if (sw_if_index_set == 0)
7835     {
7836       errmsg ("missing vpp interface name. ");
7837       return -99;
7838     }
7839
7840   /* Construct the API message */
7841   M (BOND_DELETE, mp);
7842
7843   mp->sw_if_index = ntohl (sw_if_index);
7844
7845   /* send it... */
7846   S (mp);
7847
7848   /* Wait for a reply... */
7849   W (ret);
7850   return ret;
7851 }
7852
7853 static int
7854 api_bond_enslave (vat_main_t * vam)
7855 {
7856   unformat_input_t *i = vam->input;
7857   vl_api_bond_enslave_t *mp;
7858   u32 bond_sw_if_index;
7859   int ret;
7860   u8 is_passive;
7861   u8 is_long_timeout;
7862   u32 bond_sw_if_index_is_set = 0;
7863   u32 sw_if_index;
7864   u8 sw_if_index_is_set = 0;
7865
7866   /* Parse args required to build the message */
7867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7868     {
7869       if (unformat (i, "sw_if_index %d", &sw_if_index))
7870         sw_if_index_is_set = 1;
7871       else if (unformat (i, "bond %u", &bond_sw_if_index))
7872         bond_sw_if_index_is_set = 1;
7873       else if (unformat (i, "passive %d", &is_passive))
7874         ;
7875       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7876         ;
7877       else
7878         break;
7879     }
7880
7881   if (bond_sw_if_index_is_set == 0)
7882     {
7883       errmsg ("Missing bond sw_if_index. ");
7884       return -99;
7885     }
7886   if (sw_if_index_is_set == 0)
7887     {
7888       errmsg ("Missing slave sw_if_index. ");
7889       return -99;
7890     }
7891
7892   /* Construct the API message */
7893   M (BOND_ENSLAVE, mp);
7894
7895   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7896   mp->sw_if_index = ntohl (sw_if_index);
7897   mp->is_long_timeout = is_long_timeout;
7898   mp->is_passive = is_passive;
7899
7900   /* send it... */
7901   S (mp);
7902
7903   /* Wait for a reply... */
7904   W (ret);
7905   return ret;
7906 }
7907
7908 static int
7909 api_bond_detach_slave (vat_main_t * vam)
7910 {
7911   unformat_input_t *i = vam->input;
7912   vl_api_bond_detach_slave_t *mp;
7913   u32 sw_if_index = ~0;
7914   u8 sw_if_index_set = 0;
7915   int ret;
7916
7917   /* Parse args required to build the message */
7918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7919     {
7920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7921         sw_if_index_set = 1;
7922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7923         sw_if_index_set = 1;
7924       else
7925         break;
7926     }
7927
7928   if (sw_if_index_set == 0)
7929     {
7930       errmsg ("missing vpp interface name. ");
7931       return -99;
7932     }
7933
7934   /* Construct the API message */
7935   M (BOND_DETACH_SLAVE, mp);
7936
7937   mp->sw_if_index = ntohl (sw_if_index);
7938
7939   /* send it... */
7940   S (mp);
7941
7942   /* Wait for a reply... */
7943   W (ret);
7944   return ret;
7945 }
7946
7947 static int
7948 api_ip_table_add_del (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_ip_table_add_del_t *mp;
7952   u32 table_id = ~0;
7953   u8 is_ipv6 = 0;
7954   u8 is_add = 1;
7955   int ret = 0;
7956
7957   /* Parse args required to build the message */
7958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (i, "ipv6"))
7961         is_ipv6 = 1;
7962       else if (unformat (i, "del"))
7963         is_add = 0;
7964       else if (unformat (i, "add"))
7965         is_add = 1;
7966       else if (unformat (i, "table %d", &table_id))
7967         ;
7968       else
7969         {
7970           clib_warning ("parse error '%U'", format_unformat_error, i);
7971           return -99;
7972         }
7973     }
7974
7975   if (~0 == table_id)
7976     {
7977       errmsg ("missing table-ID");
7978       return -99;
7979     }
7980
7981   /* Construct the API message */
7982   M (IP_TABLE_ADD_DEL, mp);
7983
7984   mp->table.table_id = ntohl (table_id);
7985   mp->table.is_ip6 = is_ipv6;
7986   mp->is_add = is_add;
7987
7988   /* send it... */
7989   S (mp);
7990
7991   /* Wait for a reply... */
7992   W (ret);
7993
7994   return ret;
7995 }
7996
7997 uword
7998 unformat_fib_path (unformat_input_t * input, va_list * args)
7999 {
8000   vat_main_t *vam = va_arg (*args, vat_main_t *);
8001   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8002   u32 weight, preference;
8003   mpls_label_t out_label;
8004
8005   clib_memset (path, 0, sizeof (*path));
8006   path->weight = 1;
8007   path->sw_if_index = ~0;
8008   path->rpf_id = ~0;
8009   path->n_labels = 0;
8010
8011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8012     {
8013       if (unformat (input, "%U %U",
8014                     unformat_vl_api_ip4_address,
8015                     &path->nh.address.ip4,
8016                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8017         {
8018           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8019         }
8020       else if (unformat (input, "%U %U",
8021                          unformat_vl_api_ip6_address,
8022                          &path->nh.address.ip6,
8023                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8024         {
8025           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8026         }
8027       else if (unformat (input, "weight %u", &weight))
8028         {
8029           path->weight = weight;
8030         }
8031       else if (unformat (input, "preference %u", &preference))
8032         {
8033           path->preference = preference;
8034         }
8035       else if (unformat (input, "%U next-hop-table %d",
8036                          unformat_vl_api_ip4_address,
8037                          &path->nh.address.ip4, &path->table_id))
8038         {
8039           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8040         }
8041       else if (unformat (input, "%U next-hop-table %d",
8042                          unformat_vl_api_ip6_address,
8043                          &path->nh.address.ip6, &path->table_id))
8044         {
8045           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8046         }
8047       else if (unformat (input, "%U",
8048                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8049         {
8050           /*
8051            * the recursive next-hops are by default in the default table
8052            */
8053           path->table_id = 0;
8054           path->sw_if_index = ~0;
8055           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8056         }
8057       else if (unformat (input, "%U",
8058                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8059         {
8060           /*
8061            * the recursive next-hops are by default in the default table
8062            */
8063           path->table_id = 0;
8064           path->sw_if_index = ~0;
8065           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8066         }
8067       else if (unformat (input, "resolve-via-host"))
8068         {
8069           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8070         }
8071       else if (unformat (input, "resolve-via-attached"))
8072         {
8073           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8074         }
8075       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8076         {
8077           path->type = FIB_API_PATH_TYPE_LOCAL;
8078           path->sw_if_index = ~0;
8079           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8080         }
8081       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8082         {
8083           path->type = FIB_API_PATH_TYPE_LOCAL;
8084           path->sw_if_index = ~0;
8085           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8086         }
8087       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8088         ;
8089       else if (unformat (input, "via-label %d", &path->nh.via_label))
8090         {
8091           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8092           path->sw_if_index = ~0;
8093         }
8094       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8095         {
8096           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8097           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8098         }
8099       else if (unformat (input, "local"))
8100         {
8101           path->type = FIB_API_PATH_TYPE_LOCAL;
8102         }
8103       else if (unformat (input, "out-labels"))
8104         {
8105           while (unformat (input, "%d", &out_label))
8106             {
8107               path->label_stack[path->n_labels].label = out_label;
8108               path->label_stack[path->n_labels].is_uniform = 0;
8109               path->label_stack[path->n_labels].ttl = 64;
8110               path->n_labels++;
8111             }
8112         }
8113       else if (unformat (input, "via"))
8114         {
8115           /* new path, back up and return */
8116           unformat_put_input (input);
8117           unformat_put_input (input);
8118           unformat_put_input (input);
8119           unformat_put_input (input);
8120           break;
8121         }
8122       else
8123         {
8124           return (0);
8125         }
8126     }
8127
8128   path->proto = ntohl (path->proto);
8129   path->type = ntohl (path->type);
8130   path->flags = ntohl (path->flags);
8131   path->table_id = ntohl (path->table_id);
8132   path->sw_if_index = ntohl (path->sw_if_index);
8133
8134   return (1);
8135 }
8136
8137 static int
8138 api_ip_route_add_del (vat_main_t * vam)
8139 {
8140   unformat_input_t *i = vam->input;
8141   vl_api_ip_route_add_del_t *mp;
8142   u32 vrf_id = 0;
8143   u8 is_add = 1;
8144   u8 is_multipath = 0;
8145   u8 prefix_set = 0;
8146   u8 path_count = 0;
8147   vl_api_prefix_t pfx = { };
8148   vl_api_fib_path_t paths[8];
8149   int count = 1;
8150   int j;
8151   f64 before = 0;
8152   u32 random_add_del = 0;
8153   u32 *random_vector = 0;
8154   u32 random_seed = 0xdeaddabe;
8155
8156   /* Parse args required to build the message */
8157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8158     {
8159       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8160         prefix_set = 1;
8161       else if (unformat (i, "del"))
8162         is_add = 0;
8163       else if (unformat (i, "add"))
8164         is_add = 1;
8165       else if (unformat (i, "vrf %d", &vrf_id))
8166         ;
8167       else if (unformat (i, "count %d", &count))
8168         ;
8169       else if (unformat (i, "random"))
8170         random_add_del = 1;
8171       else if (unformat (i, "multipath"))
8172         is_multipath = 1;
8173       else if (unformat (i, "seed %d", &random_seed))
8174         ;
8175       else
8176         if (unformat
8177             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8178         {
8179           path_count++;
8180           if (8 == path_count)
8181             {
8182               errmsg ("max 8 paths");
8183               return -99;
8184             }
8185         }
8186       else
8187         {
8188           clib_warning ("parse error '%U'", format_unformat_error, i);
8189           return -99;
8190         }
8191     }
8192
8193   if (!path_count)
8194     {
8195       errmsg ("specify a path; via ...");
8196       return -99;
8197     }
8198   if (prefix_set == 0)
8199     {
8200       errmsg ("missing prefix");
8201       return -99;
8202     }
8203
8204   /* Generate a pile of unique, random routes */
8205   if (random_add_del)
8206     {
8207       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8208       u32 this_random_address;
8209       uword *random_hash;
8210
8211       random_hash = hash_create (count, sizeof (uword));
8212
8213       hash_set (random_hash, i->as_u32, 1);
8214       for (j = 0; j <= count; j++)
8215         {
8216           do
8217             {
8218               this_random_address = random_u32 (&random_seed);
8219               this_random_address =
8220                 clib_host_to_net_u32 (this_random_address);
8221             }
8222           while (hash_get (random_hash, this_random_address));
8223           vec_add1 (random_vector, this_random_address);
8224           hash_set (random_hash, this_random_address, 1);
8225         }
8226       hash_free (random_hash);
8227       set_ip4_address (&pfx.address, random_vector[0]);
8228     }
8229
8230   if (count > 1)
8231     {
8232       /* Turn on async mode */
8233       vam->async_mode = 1;
8234       vam->async_errors = 0;
8235       before = vat_time_now (vam);
8236     }
8237
8238   for (j = 0; j < count; j++)
8239     {
8240       /* Construct the API message */
8241       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8242
8243       mp->is_add = is_add;
8244       mp->is_multipath = is_multipath;
8245
8246       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8247       mp->route.table_id = ntohl (vrf_id);
8248       mp->route.n_paths = path_count;
8249
8250       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8251
8252       if (random_add_del)
8253         set_ip4_address (&pfx.address, random_vector[j + 1]);
8254       else
8255         increment_address (&pfx.address);
8256       /* send it... */
8257       S (mp);
8258       /* If we receive SIGTERM, stop now... */
8259       if (vam->do_exit)
8260         break;
8261     }
8262
8263   /* When testing multiple add/del ops, use a control-ping to sync */
8264   if (count > 1)
8265     {
8266       vl_api_control_ping_t *mp_ping;
8267       f64 after;
8268       f64 timeout;
8269
8270       /* Shut off async mode */
8271       vam->async_mode = 0;
8272
8273       MPING (CONTROL_PING, mp_ping);
8274       S (mp_ping);
8275
8276       timeout = vat_time_now (vam) + 1.0;
8277       while (vat_time_now (vam) < timeout)
8278         if (vam->result_ready == 1)
8279           goto out;
8280       vam->retval = -99;
8281
8282     out:
8283       if (vam->retval == -99)
8284         errmsg ("timeout");
8285
8286       if (vam->async_errors > 0)
8287         {
8288           errmsg ("%d asynchronous errors", vam->async_errors);
8289           vam->retval = -98;
8290         }
8291       vam->async_errors = 0;
8292       after = vat_time_now (vam);
8293
8294       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8295       if (j > 0)
8296         count = j;
8297
8298       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8299              count, after - before, count / (after - before));
8300     }
8301   else
8302     {
8303       int ret;
8304
8305       /* Wait for a reply... */
8306       W (ret);
8307       return ret;
8308     }
8309
8310   /* Return the good/bad news */
8311   return (vam->retval);
8312 }
8313
8314 static int
8315 api_ip_mroute_add_del (vat_main_t * vam)
8316 {
8317   unformat_input_t *i = vam->input;
8318   u8 path_set = 0, prefix_set = 0, is_add = 1;
8319   vl_api_ip_mroute_add_del_t *mp;
8320   mfib_entry_flags_t eflags = 0;
8321   vl_api_mfib_path_t path;
8322   vl_api_mprefix_t pfx = { };
8323   u32 vrf_id = 0;
8324   int ret;
8325
8326   /* Parse args required to build the message */
8327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8328     {
8329       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8330         {
8331           prefix_set = 1;
8332           pfx.grp_address_length = htons (pfx.grp_address_length);
8333         }
8334       else if (unformat (i, "del"))
8335         is_add = 0;
8336       else if (unformat (i, "add"))
8337         is_add = 1;
8338       else if (unformat (i, "vrf %d", &vrf_id))
8339         ;
8340       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8341         path.itf_flags = htonl (path.itf_flags);
8342       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8343         ;
8344       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8345         path_set = 1;
8346       else
8347         {
8348           clib_warning ("parse error '%U'", format_unformat_error, i);
8349           return -99;
8350         }
8351     }
8352
8353   if (prefix_set == 0)
8354     {
8355       errmsg ("missing addresses\n");
8356       return -99;
8357     }
8358   if (path_set == 0)
8359     {
8360       errmsg ("missing path\n");
8361       return -99;
8362     }
8363
8364   /* Construct the API message */
8365   M (IP_MROUTE_ADD_DEL, mp);
8366
8367   mp->is_add = is_add;
8368   mp->is_multipath = 1;
8369
8370   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8371   mp->route.table_id = htonl (vrf_id);
8372   mp->route.n_paths = 1;
8373   mp->route.entry_flags = htonl (eflags);
8374
8375   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8376
8377   /* send it... */
8378   S (mp);
8379   /* Wait for a reply... */
8380   W (ret);
8381   return ret;
8382 }
8383
8384 static int
8385 api_mpls_table_add_del (vat_main_t * vam)
8386 {
8387   unformat_input_t *i = vam->input;
8388   vl_api_mpls_table_add_del_t *mp;
8389   u32 table_id = ~0;
8390   u8 is_add = 1;
8391   int ret = 0;
8392
8393   /* Parse args required to build the message */
8394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8395     {
8396       if (unformat (i, "table %d", &table_id))
8397         ;
8398       else if (unformat (i, "del"))
8399         is_add = 0;
8400       else if (unformat (i, "add"))
8401         is_add = 1;
8402       else
8403         {
8404           clib_warning ("parse error '%U'", format_unformat_error, i);
8405           return -99;
8406         }
8407     }
8408
8409   if (~0 == table_id)
8410     {
8411       errmsg ("missing table-ID");
8412       return -99;
8413     }
8414
8415   /* Construct the API message */
8416   M (MPLS_TABLE_ADD_DEL, mp);
8417
8418   mp->mt_table.mt_table_id = ntohl (table_id);
8419   mp->mt_is_add = is_add;
8420
8421   /* send it... */
8422   S (mp);
8423
8424   /* Wait for a reply... */
8425   W (ret);
8426
8427   return ret;
8428 }
8429
8430 static int
8431 api_mpls_route_add_del (vat_main_t * vam)
8432 {
8433   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8434   mpls_label_t local_label = MPLS_LABEL_INVALID;
8435   unformat_input_t *i = vam->input;
8436   vl_api_mpls_route_add_del_t *mp;
8437   vl_api_fib_path_t paths[8];
8438   int count = 1, j;
8439   f64 before = 0;
8440
8441   /* Parse args required to build the message */
8442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8443     {
8444       if (unformat (i, "%d", &local_label))
8445         ;
8446       else if (unformat (i, "eos"))
8447         is_eos = 1;
8448       else if (unformat (i, "non-eos"))
8449         is_eos = 0;
8450       else if (unformat (i, "del"))
8451         is_add = 0;
8452       else if (unformat (i, "add"))
8453         is_add = 1;
8454       else if (unformat (i, "multipath"))
8455         is_multipath = 1;
8456       else if (unformat (i, "count %d", &count))
8457         ;
8458       else
8459         if (unformat
8460             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8461         {
8462           path_count++;
8463           if (8 == path_count)
8464             {
8465               errmsg ("max 8 paths");
8466               return -99;
8467             }
8468         }
8469       else
8470         {
8471           clib_warning ("parse error '%U'", format_unformat_error, i);
8472           return -99;
8473         }
8474     }
8475
8476   if (!path_count)
8477     {
8478       errmsg ("specify a path; via ...");
8479       return -99;
8480     }
8481
8482   if (MPLS_LABEL_INVALID == local_label)
8483     {
8484       errmsg ("missing label");
8485       return -99;
8486     }
8487
8488   if (count > 1)
8489     {
8490       /* Turn on async mode */
8491       vam->async_mode = 1;
8492       vam->async_errors = 0;
8493       before = vat_time_now (vam);
8494     }
8495
8496   for (j = 0; j < count; j++)
8497     {
8498       /* Construct the API message */
8499       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8500
8501       mp->mr_is_add = is_add;
8502       mp->mr_is_multipath = is_multipath;
8503
8504       mp->mr_route.mr_label = local_label;
8505       mp->mr_route.mr_eos = is_eos;
8506       mp->mr_route.mr_table_id = 0;
8507       mp->mr_route.mr_n_paths = path_count;
8508
8509       clib_memcpy (&mp->mr_route.mr_paths, paths,
8510                    sizeof (paths[0]) * path_count);
8511
8512       local_label++;
8513
8514       /* send it... */
8515       S (mp);
8516       /* If we receive SIGTERM, stop now... */
8517       if (vam->do_exit)
8518         break;
8519     }
8520
8521   /* When testing multiple add/del ops, use a control-ping to sync */
8522   if (count > 1)
8523     {
8524       vl_api_control_ping_t *mp_ping;
8525       f64 after;
8526       f64 timeout;
8527
8528       /* Shut off async mode */
8529       vam->async_mode = 0;
8530
8531       MPING (CONTROL_PING, mp_ping);
8532       S (mp_ping);
8533
8534       timeout = vat_time_now (vam) + 1.0;
8535       while (vat_time_now (vam) < timeout)
8536         if (vam->result_ready == 1)
8537           goto out;
8538       vam->retval = -99;
8539
8540     out:
8541       if (vam->retval == -99)
8542         errmsg ("timeout");
8543
8544       if (vam->async_errors > 0)
8545         {
8546           errmsg ("%d asynchronous errors", vam->async_errors);
8547           vam->retval = -98;
8548         }
8549       vam->async_errors = 0;
8550       after = vat_time_now (vam);
8551
8552       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8553       if (j > 0)
8554         count = j;
8555
8556       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8557              count, after - before, count / (after - before));
8558     }
8559   else
8560     {
8561       int ret;
8562
8563       /* Wait for a reply... */
8564       W (ret);
8565       return ret;
8566     }
8567
8568   /* Return the good/bad news */
8569   return (vam->retval);
8570   return (0);
8571 }
8572
8573 static int
8574 api_mpls_ip_bind_unbind (vat_main_t * vam)
8575 {
8576   unformat_input_t *i = vam->input;
8577   vl_api_mpls_ip_bind_unbind_t *mp;
8578   u32 ip_table_id = 0;
8579   u8 is_bind = 1;
8580   vl_api_prefix_t pfx;
8581   u8 prefix_set = 0;
8582   mpls_label_t local_label = MPLS_LABEL_INVALID;
8583   int ret;
8584
8585   /* Parse args required to build the message */
8586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8587     {
8588       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8589         prefix_set = 1;
8590       else if (unformat (i, "%d", &local_label))
8591         ;
8592       else if (unformat (i, "table-id %d", &ip_table_id))
8593         ;
8594       else if (unformat (i, "unbind"))
8595         is_bind = 0;
8596       else if (unformat (i, "bind"))
8597         is_bind = 1;
8598       else
8599         {
8600           clib_warning ("parse error '%U'", format_unformat_error, i);
8601           return -99;
8602         }
8603     }
8604
8605   if (!prefix_set)
8606     {
8607       errmsg ("IP prefix not set");
8608       return -99;
8609     }
8610
8611   if (MPLS_LABEL_INVALID == local_label)
8612     {
8613       errmsg ("missing label");
8614       return -99;
8615     }
8616
8617   /* Construct the API message */
8618   M (MPLS_IP_BIND_UNBIND, mp);
8619
8620   mp->mb_is_bind = is_bind;
8621   mp->mb_ip_table_id = ntohl (ip_table_id);
8622   mp->mb_mpls_table_id = 0;
8623   mp->mb_label = ntohl (local_label);
8624   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8625
8626   /* send it... */
8627   S (mp);
8628
8629   /* Wait for a reply... */
8630   W (ret);
8631   return ret;
8632   return (0);
8633 }
8634
8635 static int
8636 api_sr_mpls_policy_add (vat_main_t * vam)
8637 {
8638   unformat_input_t *i = vam->input;
8639   vl_api_sr_mpls_policy_add_t *mp;
8640   u32 bsid = 0;
8641   u32 weight = 1;
8642   u8 type = 0;
8643   u8 n_segments = 0;
8644   u32 sid;
8645   u32 *segments = NULL;
8646   int ret;
8647
8648   /* Parse args required to build the message */
8649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8650     {
8651       if (unformat (i, "bsid %d", &bsid))
8652         ;
8653       else if (unformat (i, "weight %d", &weight))
8654         ;
8655       else if (unformat (i, "spray"))
8656         type = 1;
8657       else if (unformat (i, "next %d", &sid))
8658         {
8659           n_segments += 1;
8660           vec_add1 (segments, htonl (sid));
8661         }
8662       else
8663         {
8664           clib_warning ("parse error '%U'", format_unformat_error, i);
8665           return -99;
8666         }
8667     }
8668
8669   if (bsid == 0)
8670     {
8671       errmsg ("bsid not set");
8672       return -99;
8673     }
8674
8675   if (n_segments == 0)
8676     {
8677       errmsg ("no sid in segment stack");
8678       return -99;
8679     }
8680
8681   /* Construct the API message */
8682   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8683
8684   mp->bsid = htonl (bsid);
8685   mp->weight = htonl (weight);
8686   mp->type = type;
8687   mp->n_segments = n_segments;
8688   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8689   vec_free (segments);
8690
8691   /* send it... */
8692   S (mp);
8693
8694   /* Wait for a reply... */
8695   W (ret);
8696   return ret;
8697 }
8698
8699 static int
8700 api_sr_mpls_policy_del (vat_main_t * vam)
8701 {
8702   unformat_input_t *i = vam->input;
8703   vl_api_sr_mpls_policy_del_t *mp;
8704   u32 bsid = 0;
8705   int ret;
8706
8707   /* Parse args required to build the message */
8708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8709     {
8710       if (unformat (i, "bsid %d", &bsid))
8711         ;
8712       else
8713         {
8714           clib_warning ("parse error '%U'", format_unformat_error, i);
8715           return -99;
8716         }
8717     }
8718
8719   if (bsid == 0)
8720     {
8721       errmsg ("bsid not set");
8722       return -99;
8723     }
8724
8725   /* Construct the API message */
8726   M (SR_MPLS_POLICY_DEL, mp);
8727
8728   mp->bsid = htonl (bsid);
8729
8730   /* send it... */
8731   S (mp);
8732
8733   /* Wait for a reply... */
8734   W (ret);
8735   return ret;
8736 }
8737
8738 static int
8739 api_bier_table_add_del (vat_main_t * vam)
8740 {
8741   unformat_input_t *i = vam->input;
8742   vl_api_bier_table_add_del_t *mp;
8743   u8 is_add = 1;
8744   u32 set = 0, sub_domain = 0, hdr_len = 3;
8745   mpls_label_t local_label = MPLS_LABEL_INVALID;
8746   int ret;
8747
8748   /* Parse args required to build the message */
8749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8750     {
8751       if (unformat (i, "sub-domain %d", &sub_domain))
8752         ;
8753       else if (unformat (i, "set %d", &set))
8754         ;
8755       else if (unformat (i, "label %d", &local_label))
8756         ;
8757       else if (unformat (i, "hdr-len %d", &hdr_len))
8758         ;
8759       else if (unformat (i, "add"))
8760         is_add = 1;
8761       else if (unformat (i, "del"))
8762         is_add = 0;
8763       else
8764         {
8765           clib_warning ("parse error '%U'", format_unformat_error, i);
8766           return -99;
8767         }
8768     }
8769
8770   if (MPLS_LABEL_INVALID == local_label)
8771     {
8772       errmsg ("missing label\n");
8773       return -99;
8774     }
8775
8776   /* Construct the API message */
8777   M (BIER_TABLE_ADD_DEL, mp);
8778
8779   mp->bt_is_add = is_add;
8780   mp->bt_label = ntohl (local_label);
8781   mp->bt_tbl_id.bt_set = set;
8782   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8783   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8784
8785   /* send it... */
8786   S (mp);
8787
8788   /* Wait for a reply... */
8789   W (ret);
8790
8791   return (ret);
8792 }
8793
8794 static int
8795 api_bier_route_add_del (vat_main_t * vam)
8796 {
8797   unformat_input_t *i = vam->input;
8798   vl_api_bier_route_add_del_t *mp;
8799   u8 is_add = 1;
8800   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8801   ip4_address_t v4_next_hop_address;
8802   ip6_address_t v6_next_hop_address;
8803   u8 next_hop_set = 0;
8804   u8 next_hop_proto_is_ip4 = 1;
8805   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8806   int ret;
8807
8808   /* Parse args required to build the message */
8809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8810     {
8811       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8812         {
8813           next_hop_proto_is_ip4 = 1;
8814           next_hop_set = 1;
8815         }
8816       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8817         {
8818           next_hop_proto_is_ip4 = 0;
8819           next_hop_set = 1;
8820         }
8821       if (unformat (i, "sub-domain %d", &sub_domain))
8822         ;
8823       else if (unformat (i, "set %d", &set))
8824         ;
8825       else if (unformat (i, "hdr-len %d", &hdr_len))
8826         ;
8827       else if (unformat (i, "bp %d", &bp))
8828         ;
8829       else if (unformat (i, "add"))
8830         is_add = 1;
8831       else if (unformat (i, "del"))
8832         is_add = 0;
8833       else if (unformat (i, "out-label %d", &next_hop_out_label))
8834         ;
8835       else
8836         {
8837           clib_warning ("parse error '%U'", format_unformat_error, i);
8838           return -99;
8839         }
8840     }
8841
8842   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8843     {
8844       errmsg ("next hop / label set\n");
8845       return -99;
8846     }
8847   if (0 == bp)
8848     {
8849       errmsg ("bit=position not set\n");
8850       return -99;
8851     }
8852
8853   /* Construct the API message */
8854   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8855
8856   mp->br_is_add = is_add;
8857   mp->br_route.br_tbl_id.bt_set = set;
8858   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8859   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8860   mp->br_route.br_bp = ntohs (bp);
8861   mp->br_route.br_n_paths = 1;
8862   mp->br_route.br_paths[0].n_labels = 1;
8863   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8864   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8865                                     FIB_API_PATH_NH_PROTO_IP4 :
8866                                     FIB_API_PATH_NH_PROTO_IP6);
8867
8868   if (next_hop_proto_is_ip4)
8869     {
8870       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8871                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8872     }
8873   else
8874     {
8875       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8876                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8877     }
8878
8879   /* send it... */
8880   S (mp);
8881
8882   /* Wait for a reply... */
8883   W (ret);
8884
8885   return (ret);
8886 }
8887
8888 static int
8889 api_proxy_arp_add_del (vat_main_t * vam)
8890 {
8891   unformat_input_t *i = vam->input;
8892   vl_api_proxy_arp_add_del_t *mp;
8893   u32 vrf_id = 0;
8894   u8 is_add = 1;
8895   vl_api_ip4_address_t lo, hi;
8896   u8 range_set = 0;
8897   int ret;
8898
8899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8900     {
8901       if (unformat (i, "vrf %d", &vrf_id))
8902         ;
8903       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8904                          unformat_vl_api_ip4_address, &hi))
8905         range_set = 1;
8906       else if (unformat (i, "del"))
8907         is_add = 0;
8908       else
8909         {
8910           clib_warning ("parse error '%U'", format_unformat_error, i);
8911           return -99;
8912         }
8913     }
8914
8915   if (range_set == 0)
8916     {
8917       errmsg ("address range not set");
8918       return -99;
8919     }
8920
8921   M (PROXY_ARP_ADD_DEL, mp);
8922
8923   mp->proxy.table_id = ntohl (vrf_id);
8924   mp->is_add = is_add;
8925   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8926   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8927
8928   S (mp);
8929   W (ret);
8930   return ret;
8931 }
8932
8933 static int
8934 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8935 {
8936   unformat_input_t *i = vam->input;
8937   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8938   u32 sw_if_index;
8939   u8 enable = 1;
8940   u8 sw_if_index_set = 0;
8941   int ret;
8942
8943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8944     {
8945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8946         sw_if_index_set = 1;
8947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8948         sw_if_index_set = 1;
8949       else if (unformat (i, "enable"))
8950         enable = 1;
8951       else if (unformat (i, "disable"))
8952         enable = 0;
8953       else
8954         {
8955           clib_warning ("parse error '%U'", format_unformat_error, i);
8956           return -99;
8957         }
8958     }
8959
8960   if (sw_if_index_set == 0)
8961     {
8962       errmsg ("missing interface name or sw_if_index");
8963       return -99;
8964     }
8965
8966   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8967
8968   mp->sw_if_index = ntohl (sw_if_index);
8969   mp->enable_disable = enable;
8970
8971   S (mp);
8972   W (ret);
8973   return ret;
8974 }
8975
8976 static int
8977 api_mpls_tunnel_add_del (vat_main_t * vam)
8978 {
8979   unformat_input_t *i = vam->input;
8980   vl_api_mpls_tunnel_add_del_t *mp;
8981
8982   vl_api_fib_path_t paths[8];
8983   u32 sw_if_index = ~0;
8984   u8 path_count = 0;
8985   u8 l2_only = 0;
8986   u8 is_add = 1;
8987   int ret;
8988
8989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8990     {
8991       if (unformat (i, "add"))
8992         is_add = 1;
8993       else
8994         if (unformat
8995             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8996         is_add = 0;
8997       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8998         is_add = 0;
8999       else if (unformat (i, "l2-only"))
9000         l2_only = 1;
9001       else
9002         if (unformat
9003             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9004         {
9005           path_count++;
9006           if (8 == path_count)
9007             {
9008               errmsg ("max 8 paths");
9009               return -99;
9010             }
9011         }
9012       else
9013         {
9014           clib_warning ("parse error '%U'", format_unformat_error, i);
9015           return -99;
9016         }
9017     }
9018
9019   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9020
9021   mp->mt_is_add = is_add;
9022   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9023   mp->mt_tunnel.mt_l2_only = l2_only;
9024   mp->mt_tunnel.mt_is_multicast = 0;
9025   mp->mt_tunnel.mt_n_paths = path_count;
9026
9027   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9028                sizeof (paths[0]) * path_count);
9029
9030   S (mp);
9031   W (ret);
9032   return ret;
9033 }
9034
9035 static int
9036 api_sw_interface_set_unnumbered (vat_main_t * vam)
9037 {
9038   unformat_input_t *i = vam->input;
9039   vl_api_sw_interface_set_unnumbered_t *mp;
9040   u32 sw_if_index;
9041   u32 unnum_sw_index = ~0;
9042   u8 is_add = 1;
9043   u8 sw_if_index_set = 0;
9044   int ret;
9045
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9049         sw_if_index_set = 1;
9050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9051         sw_if_index_set = 1;
9052       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9053         ;
9054       else if (unformat (i, "del"))
9055         is_add = 0;
9056       else
9057         {
9058           clib_warning ("parse error '%U'", format_unformat_error, i);
9059           return -99;
9060         }
9061     }
9062
9063   if (sw_if_index_set == 0)
9064     {
9065       errmsg ("missing interface name or sw_if_index");
9066       return -99;
9067     }
9068
9069   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9070
9071   mp->sw_if_index = ntohl (sw_if_index);
9072   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9073   mp->is_add = is_add;
9074
9075   S (mp);
9076   W (ret);
9077   return ret;
9078 }
9079
9080 static int
9081 api_ip_neighbor_add_del (vat_main_t * vam)
9082 {
9083   vl_api_mac_address_t mac_address;
9084   unformat_input_t *i = vam->input;
9085   vl_api_ip_neighbor_add_del_t *mp;
9086   vl_api_address_t ip_address;
9087   u32 sw_if_index;
9088   u8 sw_if_index_set = 0;
9089   u8 is_add = 1;
9090   u8 mac_set = 0;
9091   u8 address_set = 0;
9092   int ret;
9093   ip_neighbor_flags_t flags;
9094
9095   flags = IP_NEIGHBOR_FLAG_NONE;
9096   clib_memset (&ip_address, 0, sizeof (ip_address));
9097   clib_memset (&mac_address, 0, sizeof (mac_address));
9098
9099   /* Parse args required to build the message */
9100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9101     {
9102       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9103         {
9104           mac_set = 1;
9105         }
9106       else if (unformat (i, "del"))
9107         is_add = 0;
9108       else
9109         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9110         sw_if_index_set = 1;
9111       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9112         sw_if_index_set = 1;
9113       else if (unformat (i, "static"))
9114         flags |= IP_NEIGHBOR_FLAG_STATIC;
9115       else if (unformat (i, "no-fib-entry"))
9116         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9117       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9118         address_set = 1;
9119       else
9120         {
9121           clib_warning ("parse error '%U'", format_unformat_error, i);
9122           return -99;
9123         }
9124     }
9125
9126   if (sw_if_index_set == 0)
9127     {
9128       errmsg ("missing interface name or sw_if_index");
9129       return -99;
9130     }
9131   if (!address_set)
9132     {
9133       errmsg ("no address set");
9134       return -99;
9135     }
9136
9137   /* Construct the API message */
9138   M (IP_NEIGHBOR_ADD_DEL, mp);
9139
9140   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9141   mp->is_add = is_add;
9142   mp->neighbor.flags = htonl (flags);
9143   if (mac_set)
9144     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9145                  sizeof (mac_address));
9146   if (address_set)
9147     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9148
9149   /* send it... */
9150   S (mp);
9151
9152   /* Wait for a reply, return good/bad news  */
9153   W (ret);
9154   return ret;
9155 }
9156
9157 static int
9158 api_create_vlan_subif (vat_main_t * vam)
9159 {
9160   unformat_input_t *i = vam->input;
9161   vl_api_create_vlan_subif_t *mp;
9162   u32 sw_if_index;
9163   u8 sw_if_index_set = 0;
9164   u32 vlan_id;
9165   u8 vlan_id_set = 0;
9166   int ret;
9167
9168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9169     {
9170       if (unformat (i, "sw_if_index %d", &sw_if_index))
9171         sw_if_index_set = 1;
9172       else
9173         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9174         sw_if_index_set = 1;
9175       else if (unformat (i, "vlan %d", &vlan_id))
9176         vlan_id_set = 1;
9177       else
9178         {
9179           clib_warning ("parse error '%U'", format_unformat_error, i);
9180           return -99;
9181         }
9182     }
9183
9184   if (sw_if_index_set == 0)
9185     {
9186       errmsg ("missing interface name or sw_if_index");
9187       return -99;
9188     }
9189
9190   if (vlan_id_set == 0)
9191     {
9192       errmsg ("missing vlan_id");
9193       return -99;
9194     }
9195   M (CREATE_VLAN_SUBIF, mp);
9196
9197   mp->sw_if_index = ntohl (sw_if_index);
9198   mp->vlan_id = ntohl (vlan_id);
9199
9200   S (mp);
9201   W (ret);
9202   return ret;
9203 }
9204
9205 #define foreach_create_subif_bit                \
9206 _(no_tags)                                      \
9207 _(one_tag)                                      \
9208 _(two_tags)                                     \
9209 _(dot1ad)                                       \
9210 _(exact_match)                                  \
9211 _(default_sub)                                  \
9212 _(outer_vlan_id_any)                            \
9213 _(inner_vlan_id_any)
9214
9215 static int
9216 api_create_subif (vat_main_t * vam)
9217 {
9218   unformat_input_t *i = vam->input;
9219   vl_api_create_subif_t *mp;
9220   u32 sw_if_index;
9221   u8 sw_if_index_set = 0;
9222   u32 sub_id;
9223   u8 sub_id_set = 0;
9224   u32 no_tags = 0;
9225   u32 one_tag = 0;
9226   u32 two_tags = 0;
9227   u32 dot1ad = 0;
9228   u32 exact_match = 0;
9229   u32 default_sub = 0;
9230   u32 outer_vlan_id_any = 0;
9231   u32 inner_vlan_id_any = 0;
9232   u32 tmp;
9233   u16 outer_vlan_id = 0;
9234   u16 inner_vlan_id = 0;
9235   int ret;
9236
9237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9238     {
9239       if (unformat (i, "sw_if_index %d", &sw_if_index))
9240         sw_if_index_set = 1;
9241       else
9242         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9243         sw_if_index_set = 1;
9244       else if (unformat (i, "sub_id %d", &sub_id))
9245         sub_id_set = 1;
9246       else if (unformat (i, "outer_vlan_id %d", &tmp))
9247         outer_vlan_id = tmp;
9248       else if (unformat (i, "inner_vlan_id %d", &tmp))
9249         inner_vlan_id = tmp;
9250
9251 #define _(a) else if (unformat (i, #a)) a = 1 ;
9252       foreach_create_subif_bit
9253 #undef _
9254         else
9255         {
9256           clib_warning ("parse error '%U'", format_unformat_error, i);
9257           return -99;
9258         }
9259     }
9260
9261   if (sw_if_index_set == 0)
9262     {
9263       errmsg ("missing interface name or sw_if_index");
9264       return -99;
9265     }
9266
9267   if (sub_id_set == 0)
9268     {
9269       errmsg ("missing sub_id");
9270       return -99;
9271     }
9272   M (CREATE_SUBIF, mp);
9273
9274   mp->sw_if_index = ntohl (sw_if_index);
9275   mp->sub_id = ntohl (sub_id);
9276
9277 #define _(a) mp->a = a;
9278   foreach_create_subif_bit;
9279 #undef _
9280
9281   mp->outer_vlan_id = ntohs (outer_vlan_id);
9282   mp->inner_vlan_id = ntohs (inner_vlan_id);
9283
9284   S (mp);
9285   W (ret);
9286   return ret;
9287 }
9288
9289 static int
9290 api_reset_fib (vat_main_t * vam)
9291 {
9292   unformat_input_t *i = vam->input;
9293   vl_api_reset_fib_t *mp;
9294   u32 vrf_id = 0;
9295   u8 is_ipv6 = 0;
9296   u8 vrf_id_set = 0;
9297
9298   int ret;
9299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9300     {
9301       if (unformat (i, "vrf %d", &vrf_id))
9302         vrf_id_set = 1;
9303       else if (unformat (i, "ipv6"))
9304         is_ipv6 = 1;
9305       else
9306         {
9307           clib_warning ("parse error '%U'", format_unformat_error, i);
9308           return -99;
9309         }
9310     }
9311
9312   if (vrf_id_set == 0)
9313     {
9314       errmsg ("missing vrf id");
9315       return -99;
9316     }
9317
9318   M (RESET_FIB, mp);
9319
9320   mp->vrf_id = ntohl (vrf_id);
9321   mp->is_ipv6 = is_ipv6;
9322
9323   S (mp);
9324   W (ret);
9325   return ret;
9326 }
9327
9328 static int
9329 api_dhcp_proxy_config (vat_main_t * vam)
9330 {
9331   unformat_input_t *i = vam->input;
9332   vl_api_dhcp_proxy_config_t *mp;
9333   u32 rx_vrf_id = 0;
9334   u32 server_vrf_id = 0;
9335   u8 is_add = 1;
9336   u8 v4_address_set = 0;
9337   u8 v6_address_set = 0;
9338   ip4_address_t v4address;
9339   ip6_address_t v6address;
9340   u8 v4_src_address_set = 0;
9341   u8 v6_src_address_set = 0;
9342   ip4_address_t v4srcaddress;
9343   ip6_address_t v6srcaddress;
9344   int ret;
9345
9346   /* Parse args required to build the message */
9347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9348     {
9349       if (unformat (i, "del"))
9350         is_add = 0;
9351       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9352         ;
9353       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9354         ;
9355       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9356         v4_address_set = 1;
9357       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9358         v6_address_set = 1;
9359       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9360         v4_src_address_set = 1;
9361       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9362         v6_src_address_set = 1;
9363       else
9364         break;
9365     }
9366
9367   if (v4_address_set && v6_address_set)
9368     {
9369       errmsg ("both v4 and v6 server addresses set");
9370       return -99;
9371     }
9372   if (!v4_address_set && !v6_address_set)
9373     {
9374       errmsg ("no server addresses set");
9375       return -99;
9376     }
9377
9378   if (v4_src_address_set && v6_src_address_set)
9379     {
9380       errmsg ("both v4 and v6  src addresses set");
9381       return -99;
9382     }
9383   if (!v4_src_address_set && !v6_src_address_set)
9384     {
9385       errmsg ("no src addresses set");
9386       return -99;
9387     }
9388
9389   if (!(v4_src_address_set && v4_address_set) &&
9390       !(v6_src_address_set && v6_address_set))
9391     {
9392       errmsg ("no matching server and src addresses set");
9393       return -99;
9394     }
9395
9396   /* Construct the API message */
9397   M (DHCP_PROXY_CONFIG, mp);
9398
9399   mp->is_add = is_add;
9400   mp->rx_vrf_id = ntohl (rx_vrf_id);
9401   mp->server_vrf_id = ntohl (server_vrf_id);
9402   if (v6_address_set)
9403     {
9404       mp->is_ipv6 = 1;
9405       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9406       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9407     }
9408   else
9409     {
9410       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9411       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9412     }
9413
9414   /* send it... */
9415   S (mp);
9416
9417   /* Wait for a reply, return good/bad news  */
9418   W (ret);
9419   return ret;
9420 }
9421
9422 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9423 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9424
9425 static void
9426 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9427 {
9428   vat_main_t *vam = &vat_main;
9429   u32 i, count = mp->count;
9430   vl_api_dhcp_server_t *s;
9431
9432   if (mp->is_ipv6)
9433     print (vam->ofp,
9434            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9435            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9436            ntohl (mp->rx_vrf_id),
9437            format_ip6_address, mp->dhcp_src_address,
9438            mp->vss_type, mp->vss_vpn_ascii_id,
9439            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9440   else
9441     print (vam->ofp,
9442            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9443            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9444            ntohl (mp->rx_vrf_id),
9445            format_ip4_address, mp->dhcp_src_address,
9446            mp->vss_type, mp->vss_vpn_ascii_id,
9447            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9448
9449   for (i = 0; i < count; i++)
9450     {
9451       s = &mp->servers[i];
9452
9453       if (mp->is_ipv6)
9454         print (vam->ofp,
9455                " Server Table-ID %d, Server Address %U",
9456                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9457       else
9458         print (vam->ofp,
9459                " Server Table-ID %d, Server Address %U",
9460                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9461     }
9462 }
9463
9464 static void vl_api_dhcp_proxy_details_t_handler_json
9465   (vl_api_dhcp_proxy_details_t * mp)
9466 {
9467   vat_main_t *vam = &vat_main;
9468   vat_json_node_t *node = NULL;
9469   u32 i, count = mp->count;
9470   struct in_addr ip4;
9471   struct in6_addr ip6;
9472   vl_api_dhcp_server_t *s;
9473
9474   if (VAT_JSON_ARRAY != vam->json_tree.type)
9475     {
9476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9477       vat_json_init_array (&vam->json_tree);
9478     }
9479   node = vat_json_array_add (&vam->json_tree);
9480
9481   vat_json_init_object (node);
9482   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9483   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9484                              sizeof (mp->vss_type));
9485   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9486                                    mp->vss_vpn_ascii_id);
9487   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9488   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9489
9490   if (mp->is_ipv6)
9491     {
9492       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9493       vat_json_object_add_ip6 (node, "src_address", ip6);
9494     }
9495   else
9496     {
9497       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9498       vat_json_object_add_ip4 (node, "src_address", ip4);
9499     }
9500
9501   for (i = 0; i < count; i++)
9502     {
9503       s = &mp->servers[i];
9504
9505       vat_json_object_add_uint (node, "server-table-id",
9506                                 ntohl (s->server_vrf_id));
9507
9508       if (mp->is_ipv6)
9509         {
9510           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9511           vat_json_object_add_ip4 (node, "src_address", ip4);
9512         }
9513       else
9514         {
9515           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9516           vat_json_object_add_ip6 (node, "server_address", ip6);
9517         }
9518     }
9519 }
9520
9521 static int
9522 api_dhcp_proxy_dump (vat_main_t * vam)
9523 {
9524   unformat_input_t *i = vam->input;
9525   vl_api_control_ping_t *mp_ping;
9526   vl_api_dhcp_proxy_dump_t *mp;
9527   u8 is_ipv6 = 0;
9528   int ret;
9529
9530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (unformat (i, "ipv6"))
9533         is_ipv6 = 1;
9534       else
9535         {
9536           clib_warning ("parse error '%U'", format_unformat_error, i);
9537           return -99;
9538         }
9539     }
9540
9541   M (DHCP_PROXY_DUMP, mp);
9542
9543   mp->is_ip6 = is_ipv6;
9544   S (mp);
9545
9546   /* Use a control ping for synchronization */
9547   MPING (CONTROL_PING, mp_ping);
9548   S (mp_ping);
9549
9550   W (ret);
9551   return ret;
9552 }
9553
9554 static int
9555 api_dhcp_proxy_set_vss (vat_main_t * vam)
9556 {
9557   unformat_input_t *i = vam->input;
9558   vl_api_dhcp_proxy_set_vss_t *mp;
9559   u8 is_ipv6 = 0;
9560   u8 is_add = 1;
9561   u32 tbl_id = ~0;
9562   u8 vss_type = VSS_TYPE_DEFAULT;
9563   u8 *vpn_ascii_id = 0;
9564   u32 oui = 0;
9565   u32 fib_id = 0;
9566   int ret;
9567
9568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9569     {
9570       if (unformat (i, "tbl_id %d", &tbl_id))
9571         ;
9572       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9573         vss_type = VSS_TYPE_ASCII;
9574       else if (unformat (i, "fib_id %d", &fib_id))
9575         vss_type = VSS_TYPE_VPN_ID;
9576       else if (unformat (i, "oui %d", &oui))
9577         vss_type = VSS_TYPE_VPN_ID;
9578       else if (unformat (i, "ipv6"))
9579         is_ipv6 = 1;
9580       else if (unformat (i, "del"))
9581         is_add = 0;
9582       else
9583         break;
9584     }
9585
9586   if (tbl_id == ~0)
9587     {
9588       errmsg ("missing tbl_id ");
9589       vec_free (vpn_ascii_id);
9590       return -99;
9591     }
9592
9593   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9594     {
9595       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9596       vec_free (vpn_ascii_id);
9597       return -99;
9598     }
9599
9600   M (DHCP_PROXY_SET_VSS, mp);
9601   mp->tbl_id = ntohl (tbl_id);
9602   mp->vss_type = vss_type;
9603   if (vpn_ascii_id)
9604     {
9605       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9606       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9607     }
9608   mp->vpn_index = ntohl (fib_id);
9609   mp->oui = ntohl (oui);
9610   mp->is_ipv6 = is_ipv6;
9611   mp->is_add = is_add;
9612
9613   S (mp);
9614   W (ret);
9615
9616   vec_free (vpn_ascii_id);
9617   return ret;
9618 }
9619
9620 static int
9621 api_dhcp_client_config (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_dhcp_client_config_t *mp;
9625   u32 sw_if_index;
9626   u8 sw_if_index_set = 0;
9627   u8 is_add = 1;
9628   u8 *hostname = 0;
9629   u8 disable_event = 0;
9630   int ret;
9631
9632   /* Parse args required to build the message */
9633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9634     {
9635       if (unformat (i, "del"))
9636         is_add = 0;
9637       else
9638         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9639         sw_if_index_set = 1;
9640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9641         sw_if_index_set = 1;
9642       else if (unformat (i, "hostname %s", &hostname))
9643         ;
9644       else if (unformat (i, "disable_event"))
9645         disable_event = 1;
9646       else
9647         break;
9648     }
9649
9650   if (sw_if_index_set == 0)
9651     {
9652       errmsg ("missing interface name or sw_if_index");
9653       return -99;
9654     }
9655
9656   if (vec_len (hostname) > 63)
9657     {
9658       errmsg ("hostname too long");
9659     }
9660   vec_add1 (hostname, 0);
9661
9662   /* Construct the API message */
9663   M (DHCP_CLIENT_CONFIG, mp);
9664
9665   mp->is_add = is_add;
9666   mp->client.sw_if_index = htonl (sw_if_index);
9667   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9668   vec_free (hostname);
9669   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9670   mp->client.pid = htonl (getpid ());
9671
9672   /* send it... */
9673   S (mp);
9674
9675   /* Wait for a reply, return good/bad news  */
9676   W (ret);
9677   return ret;
9678 }
9679
9680 static int
9681 api_set_ip_flow_hash (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_set_ip_flow_hash_t *mp;
9685   u32 vrf_id = 0;
9686   u8 is_ipv6 = 0;
9687   u8 vrf_id_set = 0;
9688   u8 src = 0;
9689   u8 dst = 0;
9690   u8 sport = 0;
9691   u8 dport = 0;
9692   u8 proto = 0;
9693   u8 reverse = 0;
9694   int ret;
9695
9696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9697     {
9698       if (unformat (i, "vrf %d", &vrf_id))
9699         vrf_id_set = 1;
9700       else if (unformat (i, "ipv6"))
9701         is_ipv6 = 1;
9702       else if (unformat (i, "src"))
9703         src = 1;
9704       else if (unformat (i, "dst"))
9705         dst = 1;
9706       else if (unformat (i, "sport"))
9707         sport = 1;
9708       else if (unformat (i, "dport"))
9709         dport = 1;
9710       else if (unformat (i, "proto"))
9711         proto = 1;
9712       else if (unformat (i, "reverse"))
9713         reverse = 1;
9714
9715       else
9716         {
9717           clib_warning ("parse error '%U'", format_unformat_error, i);
9718           return -99;
9719         }
9720     }
9721
9722   if (vrf_id_set == 0)
9723     {
9724       errmsg ("missing vrf id");
9725       return -99;
9726     }
9727
9728   M (SET_IP_FLOW_HASH, mp);
9729   mp->src = src;
9730   mp->dst = dst;
9731   mp->sport = sport;
9732   mp->dport = dport;
9733   mp->proto = proto;
9734   mp->reverse = reverse;
9735   mp->vrf_id = ntohl (vrf_id);
9736   mp->is_ipv6 = is_ipv6;
9737
9738   S (mp);
9739   W (ret);
9740   return ret;
9741 }
9742
9743 static int
9744 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9745 {
9746   unformat_input_t *i = vam->input;
9747   vl_api_sw_interface_ip6_enable_disable_t *mp;
9748   u32 sw_if_index;
9749   u8 sw_if_index_set = 0;
9750   u8 enable = 0;
9751   int ret;
9752
9753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9754     {
9755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9756         sw_if_index_set = 1;
9757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9758         sw_if_index_set = 1;
9759       else if (unformat (i, "enable"))
9760         enable = 1;
9761       else if (unformat (i, "disable"))
9762         enable = 0;
9763       else
9764         {
9765           clib_warning ("parse error '%U'", format_unformat_error, i);
9766           return -99;
9767         }
9768     }
9769
9770   if (sw_if_index_set == 0)
9771     {
9772       errmsg ("missing interface name or sw_if_index");
9773       return -99;
9774     }
9775
9776   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9777
9778   mp->sw_if_index = ntohl (sw_if_index);
9779   mp->enable = enable;
9780
9781   S (mp);
9782   W (ret);
9783   return ret;
9784 }
9785
9786 static int
9787 api_ip6nd_proxy_add_del (vat_main_t * vam)
9788 {
9789   unformat_input_t *i = vam->input;
9790   vl_api_ip6nd_proxy_add_del_t *mp;
9791   u32 sw_if_index = ~0;
9792   u8 v6_address_set = 0;
9793   vl_api_ip6_address_t v6address;
9794   u8 is_del = 0;
9795   int ret;
9796
9797   /* Parse args required to build the message */
9798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9799     {
9800       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9801         ;
9802       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9803         ;
9804       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9805         v6_address_set = 1;
9806       if (unformat (i, "del"))
9807         is_del = 1;
9808       else
9809         {
9810           clib_warning ("parse error '%U'", format_unformat_error, i);
9811           return -99;
9812         }
9813     }
9814
9815   if (sw_if_index == ~0)
9816     {
9817       errmsg ("missing interface name or sw_if_index");
9818       return -99;
9819     }
9820   if (!v6_address_set)
9821     {
9822       errmsg ("no address set");
9823       return -99;
9824     }
9825
9826   /* Construct the API message */
9827   M (IP6ND_PROXY_ADD_DEL, mp);
9828
9829   mp->is_del = is_del;
9830   mp->sw_if_index = ntohl (sw_if_index);
9831   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9832
9833   /* send it... */
9834   S (mp);
9835
9836   /* Wait for a reply, return good/bad news  */
9837   W (ret);
9838   return ret;
9839 }
9840
9841 static int
9842 api_ip6nd_proxy_dump (vat_main_t * vam)
9843 {
9844   vl_api_ip6nd_proxy_dump_t *mp;
9845   vl_api_control_ping_t *mp_ping;
9846   int ret;
9847
9848   M (IP6ND_PROXY_DUMP, mp);
9849
9850   S (mp);
9851
9852   /* Use a control ping for synchronization */
9853   MPING (CONTROL_PING, mp_ping);
9854   S (mp_ping);
9855
9856   W (ret);
9857   return ret;
9858 }
9859
9860 static void vl_api_ip6nd_proxy_details_t_handler
9861   (vl_api_ip6nd_proxy_details_t * mp)
9862 {
9863   vat_main_t *vam = &vat_main;
9864
9865   print (vam->ofp, "host %U sw_if_index %d",
9866          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9867 }
9868
9869 static void vl_api_ip6nd_proxy_details_t_handler_json
9870   (vl_api_ip6nd_proxy_details_t * mp)
9871 {
9872   vat_main_t *vam = &vat_main;
9873   struct in6_addr ip6;
9874   vat_json_node_t *node = NULL;
9875
9876   if (VAT_JSON_ARRAY != vam->json_tree.type)
9877     {
9878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9879       vat_json_init_array (&vam->json_tree);
9880     }
9881   node = vat_json_array_add (&vam->json_tree);
9882
9883   vat_json_init_object (node);
9884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9885
9886   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9887   vat_json_object_add_ip6 (node, "host", ip6);
9888 }
9889
9890 static int
9891 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9892 {
9893   unformat_input_t *i = vam->input;
9894   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9895   u32 sw_if_index;
9896   u8 sw_if_index_set = 0;
9897   u8 v6_address_set = 0;
9898   vl_api_prefix_t pfx;
9899   u8 use_default = 0;
9900   u8 no_advertise = 0;
9901   u8 off_link = 0;
9902   u8 no_autoconfig = 0;
9903   u8 no_onlink = 0;
9904   u8 is_no = 0;
9905   u32 val_lifetime = 0;
9906   u32 pref_lifetime = 0;
9907   int ret;
9908
9909   /* Parse args required to build the message */
9910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9911     {
9912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9913         sw_if_index_set = 1;
9914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9917         v6_address_set = 1;
9918       else if (unformat (i, "val_life %d", &val_lifetime))
9919         ;
9920       else if (unformat (i, "pref_life %d", &pref_lifetime))
9921         ;
9922       else if (unformat (i, "def"))
9923         use_default = 1;
9924       else if (unformat (i, "noadv"))
9925         no_advertise = 1;
9926       else if (unformat (i, "offl"))
9927         off_link = 1;
9928       else if (unformat (i, "noauto"))
9929         no_autoconfig = 1;
9930       else if (unformat (i, "nolink"))
9931         no_onlink = 1;
9932       else if (unformat (i, "isno"))
9933         is_no = 1;
9934       else
9935         {
9936           clib_warning ("parse error '%U'", format_unformat_error, i);
9937           return -99;
9938         }
9939     }
9940
9941   if (sw_if_index_set == 0)
9942     {
9943       errmsg ("missing interface name or sw_if_index");
9944       return -99;
9945     }
9946   if (!v6_address_set)
9947     {
9948       errmsg ("no address set");
9949       return -99;
9950     }
9951
9952   /* Construct the API message */
9953   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9954
9955   mp->sw_if_index = ntohl (sw_if_index);
9956   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9957   mp->use_default = use_default;
9958   mp->no_advertise = no_advertise;
9959   mp->off_link = off_link;
9960   mp->no_autoconfig = no_autoconfig;
9961   mp->no_onlink = no_onlink;
9962   mp->is_no = is_no;
9963   mp->val_lifetime = ntohl (val_lifetime);
9964   mp->pref_lifetime = ntohl (pref_lifetime);
9965
9966   /* send it... */
9967   S (mp);
9968
9969   /* Wait for a reply, return good/bad news  */
9970   W (ret);
9971   return ret;
9972 }
9973
9974 static int
9975 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9976 {
9977   unformat_input_t *i = vam->input;
9978   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9979   u32 sw_if_index;
9980   u8 sw_if_index_set = 0;
9981   u8 suppress = 0;
9982   u8 managed = 0;
9983   u8 other = 0;
9984   u8 ll_option = 0;
9985   u8 send_unicast = 0;
9986   u8 cease = 0;
9987   u8 is_no = 0;
9988   u8 default_router = 0;
9989   u32 max_interval = 0;
9990   u32 min_interval = 0;
9991   u32 lifetime = 0;
9992   u32 initial_count = 0;
9993   u32 initial_interval = 0;
9994   int ret;
9995
9996
9997   /* Parse args required to build the message */
9998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9999     {
10000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10001         sw_if_index_set = 1;
10002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10003         sw_if_index_set = 1;
10004       else if (unformat (i, "maxint %d", &max_interval))
10005         ;
10006       else if (unformat (i, "minint %d", &min_interval))
10007         ;
10008       else if (unformat (i, "life %d", &lifetime))
10009         ;
10010       else if (unformat (i, "count %d", &initial_count))
10011         ;
10012       else if (unformat (i, "interval %d", &initial_interval))
10013         ;
10014       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10015         suppress = 1;
10016       else if (unformat (i, "managed"))
10017         managed = 1;
10018       else if (unformat (i, "other"))
10019         other = 1;
10020       else if (unformat (i, "ll"))
10021         ll_option = 1;
10022       else if (unformat (i, "send"))
10023         send_unicast = 1;
10024       else if (unformat (i, "cease"))
10025         cease = 1;
10026       else if (unformat (i, "isno"))
10027         is_no = 1;
10028       else if (unformat (i, "def"))
10029         default_router = 1;
10030       else
10031         {
10032           clib_warning ("parse error '%U'", format_unformat_error, i);
10033           return -99;
10034         }
10035     }
10036
10037   if (sw_if_index_set == 0)
10038     {
10039       errmsg ("missing interface name or sw_if_index");
10040       return -99;
10041     }
10042
10043   /* Construct the API message */
10044   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10045
10046   mp->sw_if_index = ntohl (sw_if_index);
10047   mp->max_interval = ntohl (max_interval);
10048   mp->min_interval = ntohl (min_interval);
10049   mp->lifetime = ntohl (lifetime);
10050   mp->initial_count = ntohl (initial_count);
10051   mp->initial_interval = ntohl (initial_interval);
10052   mp->suppress = suppress;
10053   mp->managed = managed;
10054   mp->other = other;
10055   mp->ll_option = ll_option;
10056   mp->send_unicast = send_unicast;
10057   mp->cease = cease;
10058   mp->is_no = is_no;
10059   mp->default_router = default_router;
10060
10061   /* send it... */
10062   S (mp);
10063
10064   /* Wait for a reply, return good/bad news  */
10065   W (ret);
10066   return ret;
10067 }
10068
10069 static int
10070 api_set_arp_neighbor_limit (vat_main_t * vam)
10071 {
10072   unformat_input_t *i = vam->input;
10073   vl_api_set_arp_neighbor_limit_t *mp;
10074   u32 arp_nbr_limit;
10075   u8 limit_set = 0;
10076   u8 is_ipv6 = 0;
10077   int ret;
10078
10079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10080     {
10081       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10082         limit_set = 1;
10083       else if (unformat (i, "ipv6"))
10084         is_ipv6 = 1;
10085       else
10086         {
10087           clib_warning ("parse error '%U'", format_unformat_error, i);
10088           return -99;
10089         }
10090     }
10091
10092   if (limit_set == 0)
10093     {
10094       errmsg ("missing limit value");
10095       return -99;
10096     }
10097
10098   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10099
10100   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10101   mp->is_ipv6 = is_ipv6;
10102
10103   S (mp);
10104   W (ret);
10105   return ret;
10106 }
10107
10108 static int
10109 api_l2_patch_add_del (vat_main_t * vam)
10110 {
10111   unformat_input_t *i = vam->input;
10112   vl_api_l2_patch_add_del_t *mp;
10113   u32 rx_sw_if_index;
10114   u8 rx_sw_if_index_set = 0;
10115   u32 tx_sw_if_index;
10116   u8 tx_sw_if_index_set = 0;
10117   u8 is_add = 1;
10118   int ret;
10119
10120   /* Parse args required to build the message */
10121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10122     {
10123       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10124         rx_sw_if_index_set = 1;
10125       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10126         tx_sw_if_index_set = 1;
10127       else if (unformat (i, "rx"))
10128         {
10129           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10130             {
10131               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10132                             &rx_sw_if_index))
10133                 rx_sw_if_index_set = 1;
10134             }
10135           else
10136             break;
10137         }
10138       else if (unformat (i, "tx"))
10139         {
10140           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10141             {
10142               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10143                             &tx_sw_if_index))
10144                 tx_sw_if_index_set = 1;
10145             }
10146           else
10147             break;
10148         }
10149       else if (unformat (i, "del"))
10150         is_add = 0;
10151       else
10152         break;
10153     }
10154
10155   if (rx_sw_if_index_set == 0)
10156     {
10157       errmsg ("missing rx interface name or rx_sw_if_index");
10158       return -99;
10159     }
10160
10161   if (tx_sw_if_index_set == 0)
10162     {
10163       errmsg ("missing tx interface name or tx_sw_if_index");
10164       return -99;
10165     }
10166
10167   M (L2_PATCH_ADD_DEL, mp);
10168
10169   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10170   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10171   mp->is_add = is_add;
10172
10173   S (mp);
10174   W (ret);
10175   return ret;
10176 }
10177
10178 u8 is_del;
10179 u8 localsid_addr[16];
10180 u8 end_psp;
10181 u8 behavior;
10182 u32 sw_if_index;
10183 u32 vlan_index;
10184 u32 fib_table;
10185 u8 nh_addr[16];
10186
10187 static int
10188 api_sr_localsid_add_del (vat_main_t * vam)
10189 {
10190   unformat_input_t *i = vam->input;
10191   vl_api_sr_localsid_add_del_t *mp;
10192
10193   u8 is_del;
10194   ip6_address_t localsid;
10195   u8 end_psp = 0;
10196   u8 behavior = ~0;
10197   u32 sw_if_index;
10198   u32 fib_table = ~(u32) 0;
10199   ip6_address_t nh_addr6;
10200   ip4_address_t nh_addr4;
10201   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10202   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10203
10204   bool nexthop_set = 0;
10205
10206   int ret;
10207
10208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10209     {
10210       if (unformat (i, "del"))
10211         is_del = 1;
10212       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10213       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10214         nexthop_set = 1;
10215       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10216         nexthop_set = 1;
10217       else if (unformat (i, "behavior %u", &behavior));
10218       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10219       else if (unformat (i, "fib-table %u", &fib_table));
10220       else if (unformat (i, "end.psp %u", &behavior));
10221       else
10222         break;
10223     }
10224
10225   M (SR_LOCALSID_ADD_DEL, mp);
10226
10227   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10228   if (nexthop_set)
10229     {
10230       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10231       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10232     }
10233   mp->behavior = behavior;
10234   mp->sw_if_index = ntohl (sw_if_index);
10235   mp->fib_table = ntohl (fib_table);
10236   mp->end_psp = end_psp;
10237   mp->is_del = is_del;
10238
10239   S (mp);
10240   W (ret);
10241   return ret;
10242 }
10243
10244 static int
10245 api_ioam_enable (vat_main_t * vam)
10246 {
10247   unformat_input_t *input = vam->input;
10248   vl_api_ioam_enable_t *mp;
10249   u32 id = 0;
10250   int has_trace_option = 0;
10251   int has_pot_option = 0;
10252   int has_seqno_option = 0;
10253   int has_analyse_option = 0;
10254   int ret;
10255
10256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10257     {
10258       if (unformat (input, "trace"))
10259         has_trace_option = 1;
10260       else if (unformat (input, "pot"))
10261         has_pot_option = 1;
10262       else if (unformat (input, "seqno"))
10263         has_seqno_option = 1;
10264       else if (unformat (input, "analyse"))
10265         has_analyse_option = 1;
10266       else
10267         break;
10268     }
10269   M (IOAM_ENABLE, mp);
10270   mp->id = htons (id);
10271   mp->seqno = has_seqno_option;
10272   mp->analyse = has_analyse_option;
10273   mp->pot_enable = has_pot_option;
10274   mp->trace_enable = has_trace_option;
10275
10276   S (mp);
10277   W (ret);
10278   return ret;
10279 }
10280
10281
10282 static int
10283 api_ioam_disable (vat_main_t * vam)
10284 {
10285   vl_api_ioam_disable_t *mp;
10286   int ret;
10287
10288   M (IOAM_DISABLE, mp);
10289   S (mp);
10290   W (ret);
10291   return ret;
10292 }
10293
10294 #define foreach_tcp_proto_field                 \
10295 _(src_port)                                     \
10296 _(dst_port)
10297
10298 #define foreach_udp_proto_field                 \
10299 _(src_port)                                     \
10300 _(dst_port)
10301
10302 #define foreach_ip4_proto_field                 \
10303 _(src_address)                                  \
10304 _(dst_address)                                  \
10305 _(tos)                                          \
10306 _(length)                                       \
10307 _(fragment_id)                                  \
10308 _(ttl)                                          \
10309 _(protocol)                                     \
10310 _(checksum)
10311
10312 typedef struct
10313 {
10314   u16 src_port, dst_port;
10315 } tcpudp_header_t;
10316
10317 #if VPP_API_TEST_BUILTIN == 0
10318 uword
10319 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10320 {
10321   u8 **maskp = va_arg (*args, u8 **);
10322   u8 *mask = 0;
10323   u8 found_something = 0;
10324   tcp_header_t *tcp;
10325
10326 #define _(a) u8 a=0;
10327   foreach_tcp_proto_field;
10328 #undef _
10329
10330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (0);
10333 #define _(a) else if (unformat (input, #a)) a=1;
10334       foreach_tcp_proto_field
10335 #undef _
10336         else
10337         break;
10338     }
10339
10340 #define _(a) found_something += a;
10341   foreach_tcp_proto_field;
10342 #undef _
10343
10344   if (found_something == 0)
10345     return 0;
10346
10347   vec_validate (mask, sizeof (*tcp) - 1);
10348
10349   tcp = (tcp_header_t *) mask;
10350
10351 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10352   foreach_tcp_proto_field;
10353 #undef _
10354
10355   *maskp = mask;
10356   return 1;
10357 }
10358
10359 uword
10360 unformat_udp_mask (unformat_input_t * input, va_list * args)
10361 {
10362   u8 **maskp = va_arg (*args, u8 **);
10363   u8 *mask = 0;
10364   u8 found_something = 0;
10365   udp_header_t *udp;
10366
10367 #define _(a) u8 a=0;
10368   foreach_udp_proto_field;
10369 #undef _
10370
10371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (0);
10374 #define _(a) else if (unformat (input, #a)) a=1;
10375       foreach_udp_proto_field
10376 #undef _
10377         else
10378         break;
10379     }
10380
10381 #define _(a) found_something += a;
10382   foreach_udp_proto_field;
10383 #undef _
10384
10385   if (found_something == 0)
10386     return 0;
10387
10388   vec_validate (mask, sizeof (*udp) - 1);
10389
10390   udp = (udp_header_t *) mask;
10391
10392 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10393   foreach_udp_proto_field;
10394 #undef _
10395
10396   *maskp = mask;
10397   return 1;
10398 }
10399
10400 uword
10401 unformat_l4_mask (unformat_input_t * input, va_list * args)
10402 {
10403   u8 **maskp = va_arg (*args, u8 **);
10404   u16 src_port = 0, dst_port = 0;
10405   tcpudp_header_t *tcpudp;
10406
10407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10408     {
10409       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10410         return 1;
10411       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10412         return 1;
10413       else if (unformat (input, "src_port"))
10414         src_port = 0xFFFF;
10415       else if (unformat (input, "dst_port"))
10416         dst_port = 0xFFFF;
10417       else
10418         return 0;
10419     }
10420
10421   if (!src_port && !dst_port)
10422     return 0;
10423
10424   u8 *mask = 0;
10425   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10426
10427   tcpudp = (tcpudp_header_t *) mask;
10428   tcpudp->src_port = src_port;
10429   tcpudp->dst_port = dst_port;
10430
10431   *maskp = mask;
10432
10433   return 1;
10434 }
10435
10436 uword
10437 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10438 {
10439   u8 **maskp = va_arg (*args, u8 **);
10440   u8 *mask = 0;
10441   u8 found_something = 0;
10442   ip4_header_t *ip;
10443
10444 #define _(a) u8 a=0;
10445   foreach_ip4_proto_field;
10446 #undef _
10447   u8 version = 0;
10448   u8 hdr_length = 0;
10449
10450
10451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10452     {
10453       if (unformat (input, "version"))
10454         version = 1;
10455       else if (unformat (input, "hdr_length"))
10456         hdr_length = 1;
10457       else if (unformat (input, "src"))
10458         src_address = 1;
10459       else if (unformat (input, "dst"))
10460         dst_address = 1;
10461       else if (unformat (input, "proto"))
10462         protocol = 1;
10463
10464 #define _(a) else if (unformat (input, #a)) a=1;
10465       foreach_ip4_proto_field
10466 #undef _
10467         else
10468         break;
10469     }
10470
10471 #define _(a) found_something += a;
10472   foreach_ip4_proto_field;
10473 #undef _
10474
10475   if (found_something == 0)
10476     return 0;
10477
10478   vec_validate (mask, sizeof (*ip) - 1);
10479
10480   ip = (ip4_header_t *) mask;
10481
10482 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10483   foreach_ip4_proto_field;
10484 #undef _
10485
10486   ip->ip_version_and_header_length = 0;
10487
10488   if (version)
10489     ip->ip_version_and_header_length |= 0xF0;
10490
10491   if (hdr_length)
10492     ip->ip_version_and_header_length |= 0x0F;
10493
10494   *maskp = mask;
10495   return 1;
10496 }
10497
10498 #define foreach_ip6_proto_field                 \
10499 _(src_address)                                  \
10500 _(dst_address)                                  \
10501 _(payload_length)                               \
10502 _(hop_limit)                                    \
10503 _(protocol)
10504
10505 uword
10506 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10507 {
10508   u8 **maskp = va_arg (*args, u8 **);
10509   u8 *mask = 0;
10510   u8 found_something = 0;
10511   ip6_header_t *ip;
10512   u32 ip_version_traffic_class_and_flow_label;
10513
10514 #define _(a) u8 a=0;
10515   foreach_ip6_proto_field;
10516 #undef _
10517   u8 version = 0;
10518   u8 traffic_class = 0;
10519   u8 flow_label = 0;
10520
10521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10522     {
10523       if (unformat (input, "version"))
10524         version = 1;
10525       else if (unformat (input, "traffic-class"))
10526         traffic_class = 1;
10527       else if (unformat (input, "flow-label"))
10528         flow_label = 1;
10529       else if (unformat (input, "src"))
10530         src_address = 1;
10531       else if (unformat (input, "dst"))
10532         dst_address = 1;
10533       else if (unformat (input, "proto"))
10534         protocol = 1;
10535
10536 #define _(a) else if (unformat (input, #a)) a=1;
10537       foreach_ip6_proto_field
10538 #undef _
10539         else
10540         break;
10541     }
10542
10543 #define _(a) found_something += a;
10544   foreach_ip6_proto_field;
10545 #undef _
10546
10547   if (found_something == 0)
10548     return 0;
10549
10550   vec_validate (mask, sizeof (*ip) - 1);
10551
10552   ip = (ip6_header_t *) mask;
10553
10554 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10555   foreach_ip6_proto_field;
10556 #undef _
10557
10558   ip_version_traffic_class_and_flow_label = 0;
10559
10560   if (version)
10561     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10562
10563   if (traffic_class)
10564     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10565
10566   if (flow_label)
10567     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10568
10569   ip->ip_version_traffic_class_and_flow_label =
10570     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10571
10572   *maskp = mask;
10573   return 1;
10574 }
10575
10576 uword
10577 unformat_l3_mask (unformat_input_t * input, va_list * args)
10578 {
10579   u8 **maskp = va_arg (*args, u8 **);
10580
10581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10582     {
10583       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10584         return 1;
10585       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10586         return 1;
10587       else
10588         break;
10589     }
10590   return 0;
10591 }
10592
10593 uword
10594 unformat_l2_mask (unformat_input_t * input, va_list * args)
10595 {
10596   u8 **maskp = va_arg (*args, u8 **);
10597   u8 *mask = 0;
10598   u8 src = 0;
10599   u8 dst = 0;
10600   u8 proto = 0;
10601   u8 tag1 = 0;
10602   u8 tag2 = 0;
10603   u8 ignore_tag1 = 0;
10604   u8 ignore_tag2 = 0;
10605   u8 cos1 = 0;
10606   u8 cos2 = 0;
10607   u8 dot1q = 0;
10608   u8 dot1ad = 0;
10609   int len = 14;
10610
10611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10612     {
10613       if (unformat (input, "src"))
10614         src = 1;
10615       else if (unformat (input, "dst"))
10616         dst = 1;
10617       else if (unformat (input, "proto"))
10618         proto = 1;
10619       else if (unformat (input, "tag1"))
10620         tag1 = 1;
10621       else if (unformat (input, "tag2"))
10622         tag2 = 1;
10623       else if (unformat (input, "ignore-tag1"))
10624         ignore_tag1 = 1;
10625       else if (unformat (input, "ignore-tag2"))
10626         ignore_tag2 = 1;
10627       else if (unformat (input, "cos1"))
10628         cos1 = 1;
10629       else if (unformat (input, "cos2"))
10630         cos2 = 1;
10631       else if (unformat (input, "dot1q"))
10632         dot1q = 1;
10633       else if (unformat (input, "dot1ad"))
10634         dot1ad = 1;
10635       else
10636         break;
10637     }
10638   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10639        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10640     return 0;
10641
10642   if (tag1 || ignore_tag1 || cos1 || dot1q)
10643     len = 18;
10644   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10645     len = 22;
10646
10647   vec_validate (mask, len - 1);
10648
10649   if (dst)
10650     clib_memset (mask, 0xff, 6);
10651
10652   if (src)
10653     clib_memset (mask + 6, 0xff, 6);
10654
10655   if (tag2 || dot1ad)
10656     {
10657       /* inner vlan tag */
10658       if (tag2)
10659         {
10660           mask[19] = 0xff;
10661           mask[18] = 0x0f;
10662         }
10663       if (cos2)
10664         mask[18] |= 0xe0;
10665       if (proto)
10666         mask[21] = mask[20] = 0xff;
10667       if (tag1)
10668         {
10669           mask[15] = 0xff;
10670           mask[14] = 0x0f;
10671         }
10672       if (cos1)
10673         mask[14] |= 0xe0;
10674       *maskp = mask;
10675       return 1;
10676     }
10677   if (tag1 | dot1q)
10678     {
10679       if (tag1)
10680         {
10681           mask[15] = 0xff;
10682           mask[14] = 0x0f;
10683         }
10684       if (cos1)
10685         mask[14] |= 0xe0;
10686       if (proto)
10687         mask[16] = mask[17] = 0xff;
10688
10689       *maskp = mask;
10690       return 1;
10691     }
10692   if (cos2)
10693     mask[18] |= 0xe0;
10694   if (cos1)
10695     mask[14] |= 0xe0;
10696   if (proto)
10697     mask[12] = mask[13] = 0xff;
10698
10699   *maskp = mask;
10700   return 1;
10701 }
10702
10703 uword
10704 unformat_classify_mask (unformat_input_t * input, va_list * args)
10705 {
10706   u8 **maskp = va_arg (*args, u8 **);
10707   u32 *skipp = va_arg (*args, u32 *);
10708   u32 *matchp = va_arg (*args, u32 *);
10709   u32 match;
10710   u8 *mask = 0;
10711   u8 *l2 = 0;
10712   u8 *l3 = 0;
10713   u8 *l4 = 0;
10714   int i;
10715
10716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10717     {
10718       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10719         ;
10720       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10721         ;
10722       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10723         ;
10724       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10725         ;
10726       else
10727         break;
10728     }
10729
10730   if (l4 && !l3)
10731     {
10732       vec_free (mask);
10733       vec_free (l2);
10734       vec_free (l4);
10735       return 0;
10736     }
10737
10738   if (mask || l2 || l3 || l4)
10739     {
10740       if (l2 || l3 || l4)
10741         {
10742           /* "With a free Ethernet header in every package" */
10743           if (l2 == 0)
10744             vec_validate (l2, 13);
10745           mask = l2;
10746           if (vec_len (l3))
10747             {
10748               vec_append (mask, l3);
10749               vec_free (l3);
10750             }
10751           if (vec_len (l4))
10752             {
10753               vec_append (mask, l4);
10754               vec_free (l4);
10755             }
10756         }
10757
10758       /* Scan forward looking for the first significant mask octet */
10759       for (i = 0; i < vec_len (mask); i++)
10760         if (mask[i])
10761           break;
10762
10763       /* compute (skip, match) params */
10764       *skipp = i / sizeof (u32x4);
10765       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10766
10767       /* Pad mask to an even multiple of the vector size */
10768       while (vec_len (mask) % sizeof (u32x4))
10769         vec_add1 (mask, 0);
10770
10771       match = vec_len (mask) / sizeof (u32x4);
10772
10773       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10774         {
10775           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10776           if (*tmp || *(tmp + 1))
10777             break;
10778           match--;
10779         }
10780       if (match == 0)
10781         clib_warning ("BUG: match 0");
10782
10783       _vec_len (mask) = match * sizeof (u32x4);
10784
10785       *matchp = match;
10786       *maskp = mask;
10787
10788       return 1;
10789     }
10790
10791   return 0;
10792 }
10793 #endif /* VPP_API_TEST_BUILTIN */
10794
10795 #define foreach_l2_next                         \
10796 _(drop, DROP)                                   \
10797 _(ethernet, ETHERNET_INPUT)                     \
10798 _(ip4, IP4_INPUT)                               \
10799 _(ip6, IP6_INPUT)
10800
10801 uword
10802 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10803 {
10804   u32 *miss_next_indexp = va_arg (*args, u32 *);
10805   u32 next_index = 0;
10806   u32 tmp;
10807
10808 #define _(n,N) \
10809   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10810   foreach_l2_next;
10811 #undef _
10812
10813   if (unformat (input, "%d", &tmp))
10814     {
10815       next_index = tmp;
10816       goto out;
10817     }
10818
10819   return 0;
10820
10821 out:
10822   *miss_next_indexp = next_index;
10823   return 1;
10824 }
10825
10826 #define foreach_ip_next                         \
10827 _(drop, DROP)                                   \
10828 _(local, LOCAL)                                 \
10829 _(rewrite, REWRITE)
10830
10831 uword
10832 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10833 {
10834   u32 *miss_next_indexp = va_arg (*args, u32 *);
10835   u32 next_index = 0;
10836   u32 tmp;
10837
10838 #define _(n,N) \
10839   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10840   foreach_ip_next;
10841 #undef _
10842
10843   if (unformat (input, "%d", &tmp))
10844     {
10845       next_index = tmp;
10846       goto out;
10847     }
10848
10849   return 0;
10850
10851 out:
10852   *miss_next_indexp = next_index;
10853   return 1;
10854 }
10855
10856 #define foreach_acl_next                        \
10857 _(deny, DENY)
10858
10859 uword
10860 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10861 {
10862   u32 *miss_next_indexp = va_arg (*args, u32 *);
10863   u32 next_index = 0;
10864   u32 tmp;
10865
10866 #define _(n,N) \
10867   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10868   foreach_acl_next;
10869 #undef _
10870
10871   if (unformat (input, "permit"))
10872     {
10873       next_index = ~0;
10874       goto out;
10875     }
10876   else if (unformat (input, "%d", &tmp))
10877     {
10878       next_index = tmp;
10879       goto out;
10880     }
10881
10882   return 0;
10883
10884 out:
10885   *miss_next_indexp = next_index;
10886   return 1;
10887 }
10888
10889 uword
10890 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10891 {
10892   u32 *r = va_arg (*args, u32 *);
10893
10894   if (unformat (input, "conform-color"))
10895     *r = POLICE_CONFORM;
10896   else if (unformat (input, "exceed-color"))
10897     *r = POLICE_EXCEED;
10898   else
10899     return 0;
10900
10901   return 1;
10902 }
10903
10904 static int
10905 api_classify_add_del_table (vat_main_t * vam)
10906 {
10907   unformat_input_t *i = vam->input;
10908   vl_api_classify_add_del_table_t *mp;
10909
10910   u32 nbuckets = 2;
10911   u32 skip = ~0;
10912   u32 match = ~0;
10913   int is_add = 1;
10914   int del_chain = 0;
10915   u32 table_index = ~0;
10916   u32 next_table_index = ~0;
10917   u32 miss_next_index = ~0;
10918   u32 memory_size = 32 << 20;
10919   u8 *mask = 0;
10920   u32 current_data_flag = 0;
10921   int current_data_offset = 0;
10922   int ret;
10923
10924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10925     {
10926       if (unformat (i, "del"))
10927         is_add = 0;
10928       else if (unformat (i, "del-chain"))
10929         {
10930           is_add = 0;
10931           del_chain = 1;
10932         }
10933       else if (unformat (i, "buckets %d", &nbuckets))
10934         ;
10935       else if (unformat (i, "memory_size %d", &memory_size))
10936         ;
10937       else if (unformat (i, "skip %d", &skip))
10938         ;
10939       else if (unformat (i, "match %d", &match))
10940         ;
10941       else if (unformat (i, "table %d", &table_index))
10942         ;
10943       else if (unformat (i, "mask %U", unformat_classify_mask,
10944                          &mask, &skip, &match))
10945         ;
10946       else if (unformat (i, "next-table %d", &next_table_index))
10947         ;
10948       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10949                          &miss_next_index))
10950         ;
10951       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10952                          &miss_next_index))
10953         ;
10954       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10955                          &miss_next_index))
10956         ;
10957       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10958         ;
10959       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10960         ;
10961       else
10962         break;
10963     }
10964
10965   if (is_add && mask == 0)
10966     {
10967       errmsg ("Mask required");
10968       return -99;
10969     }
10970
10971   if (is_add && skip == ~0)
10972     {
10973       errmsg ("skip count required");
10974       return -99;
10975     }
10976
10977   if (is_add && match == ~0)
10978     {
10979       errmsg ("match count required");
10980       return -99;
10981     }
10982
10983   if (!is_add && table_index == ~0)
10984     {
10985       errmsg ("table index required for delete");
10986       return -99;
10987     }
10988
10989   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10990
10991   mp->is_add = is_add;
10992   mp->del_chain = del_chain;
10993   mp->table_index = ntohl (table_index);
10994   mp->nbuckets = ntohl (nbuckets);
10995   mp->memory_size = ntohl (memory_size);
10996   mp->skip_n_vectors = ntohl (skip);
10997   mp->match_n_vectors = ntohl (match);
10998   mp->next_table_index = ntohl (next_table_index);
10999   mp->miss_next_index = ntohl (miss_next_index);
11000   mp->current_data_flag = ntohl (current_data_flag);
11001   mp->current_data_offset = ntohl (current_data_offset);
11002   mp->mask_len = ntohl (vec_len (mask));
11003   clib_memcpy (mp->mask, mask, vec_len (mask));
11004
11005   vec_free (mask);
11006
11007   S (mp);
11008   W (ret);
11009   return ret;
11010 }
11011
11012 #if VPP_API_TEST_BUILTIN == 0
11013 uword
11014 unformat_l4_match (unformat_input_t * input, va_list * args)
11015 {
11016   u8 **matchp = va_arg (*args, u8 **);
11017
11018   u8 *proto_header = 0;
11019   int src_port = 0;
11020   int dst_port = 0;
11021
11022   tcpudp_header_t h;
11023
11024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11025     {
11026       if (unformat (input, "src_port %d", &src_port))
11027         ;
11028       else if (unformat (input, "dst_port %d", &dst_port))
11029         ;
11030       else
11031         return 0;
11032     }
11033
11034   h.src_port = clib_host_to_net_u16 (src_port);
11035   h.dst_port = clib_host_to_net_u16 (dst_port);
11036   vec_validate (proto_header, sizeof (h) - 1);
11037   memcpy (proto_header, &h, sizeof (h));
11038
11039   *matchp = proto_header;
11040
11041   return 1;
11042 }
11043
11044 uword
11045 unformat_ip4_match (unformat_input_t * input, va_list * args)
11046 {
11047   u8 **matchp = va_arg (*args, u8 **);
11048   u8 *match = 0;
11049   ip4_header_t *ip;
11050   int version = 0;
11051   u32 version_val;
11052   int hdr_length = 0;
11053   u32 hdr_length_val;
11054   int src = 0, dst = 0;
11055   ip4_address_t src_val, dst_val;
11056   int proto = 0;
11057   u32 proto_val;
11058   int tos = 0;
11059   u32 tos_val;
11060   int length = 0;
11061   u32 length_val;
11062   int fragment_id = 0;
11063   u32 fragment_id_val;
11064   int ttl = 0;
11065   int ttl_val;
11066   int checksum = 0;
11067   u32 checksum_val;
11068
11069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11070     {
11071       if (unformat (input, "version %d", &version_val))
11072         version = 1;
11073       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11074         hdr_length = 1;
11075       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11076         src = 1;
11077       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11078         dst = 1;
11079       else if (unformat (input, "proto %d", &proto_val))
11080         proto = 1;
11081       else if (unformat (input, "tos %d", &tos_val))
11082         tos = 1;
11083       else if (unformat (input, "length %d", &length_val))
11084         length = 1;
11085       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11086         fragment_id = 1;
11087       else if (unformat (input, "ttl %d", &ttl_val))
11088         ttl = 1;
11089       else if (unformat (input, "checksum %d", &checksum_val))
11090         checksum = 1;
11091       else
11092         break;
11093     }
11094
11095   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11096       + ttl + checksum == 0)
11097     return 0;
11098
11099   /*
11100    * Aligned because we use the real comparison functions
11101    */
11102   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11103
11104   ip = (ip4_header_t *) match;
11105
11106   /* These are realistically matched in practice */
11107   if (src)
11108     ip->src_address.as_u32 = src_val.as_u32;
11109
11110   if (dst)
11111     ip->dst_address.as_u32 = dst_val.as_u32;
11112
11113   if (proto)
11114     ip->protocol = proto_val;
11115
11116
11117   /* These are not, but they're included for completeness */
11118   if (version)
11119     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11120
11121   if (hdr_length)
11122     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11123
11124   if (tos)
11125     ip->tos = tos_val;
11126
11127   if (length)
11128     ip->length = clib_host_to_net_u16 (length_val);
11129
11130   if (ttl)
11131     ip->ttl = ttl_val;
11132
11133   if (checksum)
11134     ip->checksum = clib_host_to_net_u16 (checksum_val);
11135
11136   *matchp = match;
11137   return 1;
11138 }
11139
11140 uword
11141 unformat_ip6_match (unformat_input_t * input, va_list * args)
11142 {
11143   u8 **matchp = va_arg (*args, u8 **);
11144   u8 *match = 0;
11145   ip6_header_t *ip;
11146   int version = 0;
11147   u32 version_val;
11148   u8 traffic_class = 0;
11149   u32 traffic_class_val = 0;
11150   u8 flow_label = 0;
11151   u8 flow_label_val;
11152   int src = 0, dst = 0;
11153   ip6_address_t src_val, dst_val;
11154   int proto = 0;
11155   u32 proto_val;
11156   int payload_length = 0;
11157   u32 payload_length_val;
11158   int hop_limit = 0;
11159   int hop_limit_val;
11160   u32 ip_version_traffic_class_and_flow_label;
11161
11162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (input, "version %d", &version_val))
11165         version = 1;
11166       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11167         traffic_class = 1;
11168       else if (unformat (input, "flow_label %d", &flow_label_val))
11169         flow_label = 1;
11170       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11171         src = 1;
11172       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11173         dst = 1;
11174       else if (unformat (input, "proto %d", &proto_val))
11175         proto = 1;
11176       else if (unformat (input, "payload_length %d", &payload_length_val))
11177         payload_length = 1;
11178       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11179         hop_limit = 1;
11180       else
11181         break;
11182     }
11183
11184   if (version + traffic_class + flow_label + src + dst + proto +
11185       payload_length + hop_limit == 0)
11186     return 0;
11187
11188   /*
11189    * Aligned because we use the real comparison functions
11190    */
11191   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11192
11193   ip = (ip6_header_t *) match;
11194
11195   if (src)
11196     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11197
11198   if (dst)
11199     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11200
11201   if (proto)
11202     ip->protocol = proto_val;
11203
11204   ip_version_traffic_class_and_flow_label = 0;
11205
11206   if (version)
11207     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11208
11209   if (traffic_class)
11210     ip_version_traffic_class_and_flow_label |=
11211       (traffic_class_val & 0xFF) << 20;
11212
11213   if (flow_label)
11214     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11215
11216   ip->ip_version_traffic_class_and_flow_label =
11217     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11218
11219   if (payload_length)
11220     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11221
11222   if (hop_limit)
11223     ip->hop_limit = hop_limit_val;
11224
11225   *matchp = match;
11226   return 1;
11227 }
11228
11229 uword
11230 unformat_l3_match (unformat_input_t * input, va_list * args)
11231 {
11232   u8 **matchp = va_arg (*args, u8 **);
11233
11234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11235     {
11236       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11237         return 1;
11238       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11239         return 1;
11240       else
11241         break;
11242     }
11243   return 0;
11244 }
11245
11246 uword
11247 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11248 {
11249   u8 *tagp = va_arg (*args, u8 *);
11250   u32 tag;
11251
11252   if (unformat (input, "%d", &tag))
11253     {
11254       tagp[0] = (tag >> 8) & 0x0F;
11255       tagp[1] = tag & 0xFF;
11256       return 1;
11257     }
11258
11259   return 0;
11260 }
11261
11262 uword
11263 unformat_l2_match (unformat_input_t * input, va_list * args)
11264 {
11265   u8 **matchp = va_arg (*args, u8 **);
11266   u8 *match = 0;
11267   u8 src = 0;
11268   u8 src_val[6];
11269   u8 dst = 0;
11270   u8 dst_val[6];
11271   u8 proto = 0;
11272   u16 proto_val;
11273   u8 tag1 = 0;
11274   u8 tag1_val[2];
11275   u8 tag2 = 0;
11276   u8 tag2_val[2];
11277   int len = 14;
11278   u8 ignore_tag1 = 0;
11279   u8 ignore_tag2 = 0;
11280   u8 cos1 = 0;
11281   u8 cos2 = 0;
11282   u32 cos1_val = 0;
11283   u32 cos2_val = 0;
11284
11285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11286     {
11287       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11288         src = 1;
11289       else
11290         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11291         dst = 1;
11292       else if (unformat (input, "proto %U",
11293                          unformat_ethernet_type_host_byte_order, &proto_val))
11294         proto = 1;
11295       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11296         tag1 = 1;
11297       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11298         tag2 = 1;
11299       else if (unformat (input, "ignore-tag1"))
11300         ignore_tag1 = 1;
11301       else if (unformat (input, "ignore-tag2"))
11302         ignore_tag2 = 1;
11303       else if (unformat (input, "cos1 %d", &cos1_val))
11304         cos1 = 1;
11305       else if (unformat (input, "cos2 %d", &cos2_val))
11306         cos2 = 1;
11307       else
11308         break;
11309     }
11310   if ((src + dst + proto + tag1 + tag2 +
11311        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11312     return 0;
11313
11314   if (tag1 || ignore_tag1 || cos1)
11315     len = 18;
11316   if (tag2 || ignore_tag2 || cos2)
11317     len = 22;
11318
11319   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11320
11321   if (dst)
11322     clib_memcpy (match, dst_val, 6);
11323
11324   if (src)
11325     clib_memcpy (match + 6, src_val, 6);
11326
11327   if (tag2)
11328     {
11329       /* inner vlan tag */
11330       match[19] = tag2_val[1];
11331       match[18] = tag2_val[0];
11332       if (cos2)
11333         match[18] |= (cos2_val & 0x7) << 5;
11334       if (proto)
11335         {
11336           match[21] = proto_val & 0xff;
11337           match[20] = proto_val >> 8;
11338         }
11339       if (tag1)
11340         {
11341           match[15] = tag1_val[1];
11342           match[14] = tag1_val[0];
11343         }
11344       if (cos1)
11345         match[14] |= (cos1_val & 0x7) << 5;
11346       *matchp = match;
11347       return 1;
11348     }
11349   if (tag1)
11350     {
11351       match[15] = tag1_val[1];
11352       match[14] = tag1_val[0];
11353       if (proto)
11354         {
11355           match[17] = proto_val & 0xff;
11356           match[16] = proto_val >> 8;
11357         }
11358       if (cos1)
11359         match[14] |= (cos1_val & 0x7) << 5;
11360
11361       *matchp = match;
11362       return 1;
11363     }
11364   if (cos2)
11365     match[18] |= (cos2_val & 0x7) << 5;
11366   if (cos1)
11367     match[14] |= (cos1_val & 0x7) << 5;
11368   if (proto)
11369     {
11370       match[13] = proto_val & 0xff;
11371       match[12] = proto_val >> 8;
11372     }
11373
11374   *matchp = match;
11375   return 1;
11376 }
11377
11378 uword
11379 unformat_qos_source (unformat_input_t * input, va_list * args)
11380 {
11381   int *qs = va_arg (*args, int *);
11382
11383   if (unformat (input, "ip"))
11384     *qs = QOS_SOURCE_IP;
11385   else if (unformat (input, "mpls"))
11386     *qs = QOS_SOURCE_MPLS;
11387   else if (unformat (input, "ext"))
11388     *qs = QOS_SOURCE_EXT;
11389   else if (unformat (input, "vlan"))
11390     *qs = QOS_SOURCE_VLAN;
11391   else
11392     return 0;
11393
11394   return 1;
11395 }
11396 #endif
11397
11398 uword
11399 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11400 {
11401   u8 **matchp = va_arg (*args, u8 **);
11402   u32 skip_n_vectors = va_arg (*args, u32);
11403   u32 match_n_vectors = va_arg (*args, u32);
11404
11405   u8 *match = 0;
11406   u8 *l2 = 0;
11407   u8 *l3 = 0;
11408   u8 *l4 = 0;
11409
11410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11411     {
11412       if (unformat (input, "hex %U", unformat_hex_string, &match))
11413         ;
11414       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11415         ;
11416       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11417         ;
11418       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11419         ;
11420       else
11421         break;
11422     }
11423
11424   if (l4 && !l3)
11425     {
11426       vec_free (match);
11427       vec_free (l2);
11428       vec_free (l4);
11429       return 0;
11430     }
11431
11432   if (match || l2 || l3 || l4)
11433     {
11434       if (l2 || l3 || l4)
11435         {
11436           /* "Win a free Ethernet header in every packet" */
11437           if (l2 == 0)
11438             vec_validate_aligned (l2, 13, sizeof (u32x4));
11439           match = l2;
11440           if (vec_len (l3))
11441             {
11442               vec_append_aligned (match, l3, sizeof (u32x4));
11443               vec_free (l3);
11444             }
11445           if (vec_len (l4))
11446             {
11447               vec_append_aligned (match, l4, sizeof (u32x4));
11448               vec_free (l4);
11449             }
11450         }
11451
11452       /* Make sure the vector is big enough even if key is all 0's */
11453       vec_validate_aligned
11454         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11455          sizeof (u32x4));
11456
11457       /* Set size, include skipped vectors */
11458       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11459
11460       *matchp = match;
11461
11462       return 1;
11463     }
11464
11465   return 0;
11466 }
11467
11468 static int
11469 api_classify_add_del_session (vat_main_t * vam)
11470 {
11471   unformat_input_t *i = vam->input;
11472   vl_api_classify_add_del_session_t *mp;
11473   int is_add = 1;
11474   u32 table_index = ~0;
11475   u32 hit_next_index = ~0;
11476   u32 opaque_index = ~0;
11477   u8 *match = 0;
11478   i32 advance = 0;
11479   u32 skip_n_vectors = 0;
11480   u32 match_n_vectors = 0;
11481   u32 action = 0;
11482   u32 metadata = 0;
11483   int ret;
11484
11485   /*
11486    * Warning: you have to supply skip_n and match_n
11487    * because the API client cant simply look at the classify
11488    * table object.
11489    */
11490
11491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11492     {
11493       if (unformat (i, "del"))
11494         is_add = 0;
11495       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11496                          &hit_next_index))
11497         ;
11498       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11499                          &hit_next_index))
11500         ;
11501       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11502                          &hit_next_index))
11503         ;
11504       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11505         ;
11506       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11507         ;
11508       else if (unformat (i, "opaque-index %d", &opaque_index))
11509         ;
11510       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11511         ;
11512       else if (unformat (i, "match_n %d", &match_n_vectors))
11513         ;
11514       else if (unformat (i, "match %U", api_unformat_classify_match,
11515                          &match, skip_n_vectors, match_n_vectors))
11516         ;
11517       else if (unformat (i, "advance %d", &advance))
11518         ;
11519       else if (unformat (i, "table-index %d", &table_index))
11520         ;
11521       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11522         action = 1;
11523       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11524         action = 2;
11525       else if (unformat (i, "action %d", &action))
11526         ;
11527       else if (unformat (i, "metadata %d", &metadata))
11528         ;
11529       else
11530         break;
11531     }
11532
11533   if (table_index == ~0)
11534     {
11535       errmsg ("Table index required");
11536       return -99;
11537     }
11538
11539   if (is_add && match == 0)
11540     {
11541       errmsg ("Match value required");
11542       return -99;
11543     }
11544
11545   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11546
11547   mp->is_add = is_add;
11548   mp->table_index = ntohl (table_index);
11549   mp->hit_next_index = ntohl (hit_next_index);
11550   mp->opaque_index = ntohl (opaque_index);
11551   mp->advance = ntohl (advance);
11552   mp->action = action;
11553   mp->metadata = ntohl (metadata);
11554   mp->match_len = ntohl (vec_len (match));
11555   clib_memcpy (mp->match, match, vec_len (match));
11556   vec_free (match);
11557
11558   S (mp);
11559   W (ret);
11560   return ret;
11561 }
11562
11563 static int
11564 api_classify_set_interface_ip_table (vat_main_t * vam)
11565 {
11566   unformat_input_t *i = vam->input;
11567   vl_api_classify_set_interface_ip_table_t *mp;
11568   u32 sw_if_index;
11569   int sw_if_index_set;
11570   u32 table_index = ~0;
11571   u8 is_ipv6 = 0;
11572   int ret;
11573
11574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11575     {
11576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11577         sw_if_index_set = 1;
11578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11579         sw_if_index_set = 1;
11580       else if (unformat (i, "table %d", &table_index))
11581         ;
11582       else
11583         {
11584           clib_warning ("parse error '%U'", format_unformat_error, i);
11585           return -99;
11586         }
11587     }
11588
11589   if (sw_if_index_set == 0)
11590     {
11591       errmsg ("missing interface name or sw_if_index");
11592       return -99;
11593     }
11594
11595
11596   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11597
11598   mp->sw_if_index = ntohl (sw_if_index);
11599   mp->table_index = ntohl (table_index);
11600   mp->is_ipv6 = is_ipv6;
11601
11602   S (mp);
11603   W (ret);
11604   return ret;
11605 }
11606
11607 static int
11608 api_classify_set_interface_l2_tables (vat_main_t * vam)
11609 {
11610   unformat_input_t *i = vam->input;
11611   vl_api_classify_set_interface_l2_tables_t *mp;
11612   u32 sw_if_index;
11613   int sw_if_index_set;
11614   u32 ip4_table_index = ~0;
11615   u32 ip6_table_index = ~0;
11616   u32 other_table_index = ~0;
11617   u32 is_input = 1;
11618   int ret;
11619
11620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11621     {
11622       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11623         sw_if_index_set = 1;
11624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11625         sw_if_index_set = 1;
11626       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11627         ;
11628       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11629         ;
11630       else if (unformat (i, "other-table %d", &other_table_index))
11631         ;
11632       else if (unformat (i, "is-input %d", &is_input))
11633         ;
11634       else
11635         {
11636           clib_warning ("parse error '%U'", format_unformat_error, i);
11637           return -99;
11638         }
11639     }
11640
11641   if (sw_if_index_set == 0)
11642     {
11643       errmsg ("missing interface name or sw_if_index");
11644       return -99;
11645     }
11646
11647
11648   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11649
11650   mp->sw_if_index = ntohl (sw_if_index);
11651   mp->ip4_table_index = ntohl (ip4_table_index);
11652   mp->ip6_table_index = ntohl (ip6_table_index);
11653   mp->other_table_index = ntohl (other_table_index);
11654   mp->is_input = (u8) is_input;
11655
11656   S (mp);
11657   W (ret);
11658   return ret;
11659 }
11660
11661 static int
11662 api_set_ipfix_exporter (vat_main_t * vam)
11663 {
11664   unformat_input_t *i = vam->input;
11665   vl_api_set_ipfix_exporter_t *mp;
11666   ip4_address_t collector_address;
11667   u8 collector_address_set = 0;
11668   u32 collector_port = ~0;
11669   ip4_address_t src_address;
11670   u8 src_address_set = 0;
11671   u32 vrf_id = ~0;
11672   u32 path_mtu = ~0;
11673   u32 template_interval = ~0;
11674   u8 udp_checksum = 0;
11675   int ret;
11676
11677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11678     {
11679       if (unformat (i, "collector_address %U", unformat_ip4_address,
11680                     &collector_address))
11681         collector_address_set = 1;
11682       else if (unformat (i, "collector_port %d", &collector_port))
11683         ;
11684       else if (unformat (i, "src_address %U", unformat_ip4_address,
11685                          &src_address))
11686         src_address_set = 1;
11687       else if (unformat (i, "vrf_id %d", &vrf_id))
11688         ;
11689       else if (unformat (i, "path_mtu %d", &path_mtu))
11690         ;
11691       else if (unformat (i, "template_interval %d", &template_interval))
11692         ;
11693       else if (unformat (i, "udp_checksum"))
11694         udp_checksum = 1;
11695       else
11696         break;
11697     }
11698
11699   if (collector_address_set == 0)
11700     {
11701       errmsg ("collector_address required");
11702       return -99;
11703     }
11704
11705   if (src_address_set == 0)
11706     {
11707       errmsg ("src_address required");
11708       return -99;
11709     }
11710
11711   M (SET_IPFIX_EXPORTER, mp);
11712
11713   memcpy (mp->collector_address, collector_address.data,
11714           sizeof (collector_address.data));
11715   mp->collector_port = htons ((u16) collector_port);
11716   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11717   mp->vrf_id = htonl (vrf_id);
11718   mp->path_mtu = htonl (path_mtu);
11719   mp->template_interval = htonl (template_interval);
11720   mp->udp_checksum = udp_checksum;
11721
11722   S (mp);
11723   W (ret);
11724   return ret;
11725 }
11726
11727 static int
11728 api_set_ipfix_classify_stream (vat_main_t * vam)
11729 {
11730   unformat_input_t *i = vam->input;
11731   vl_api_set_ipfix_classify_stream_t *mp;
11732   u32 domain_id = 0;
11733   u32 src_port = UDP_DST_PORT_ipfix;
11734   int ret;
11735
11736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11737     {
11738       if (unformat (i, "domain %d", &domain_id))
11739         ;
11740       else if (unformat (i, "src_port %d", &src_port))
11741         ;
11742       else
11743         {
11744           errmsg ("unknown input `%U'", format_unformat_error, i);
11745           return -99;
11746         }
11747     }
11748
11749   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11750
11751   mp->domain_id = htonl (domain_id);
11752   mp->src_port = htons ((u16) src_port);
11753
11754   S (mp);
11755   W (ret);
11756   return ret;
11757 }
11758
11759 static int
11760 api_ipfix_classify_table_add_del (vat_main_t * vam)
11761 {
11762   unformat_input_t *i = vam->input;
11763   vl_api_ipfix_classify_table_add_del_t *mp;
11764   int is_add = -1;
11765   u32 classify_table_index = ~0;
11766   u8 ip_version = 0;
11767   u8 transport_protocol = 255;
11768   int ret;
11769
11770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11771     {
11772       if (unformat (i, "add"))
11773         is_add = 1;
11774       else if (unformat (i, "del"))
11775         is_add = 0;
11776       else if (unformat (i, "table %d", &classify_table_index))
11777         ;
11778       else if (unformat (i, "ip4"))
11779         ip_version = 4;
11780       else if (unformat (i, "ip6"))
11781         ip_version = 6;
11782       else if (unformat (i, "tcp"))
11783         transport_protocol = 6;
11784       else if (unformat (i, "udp"))
11785         transport_protocol = 17;
11786       else
11787         {
11788           errmsg ("unknown input `%U'", format_unformat_error, i);
11789           return -99;
11790         }
11791     }
11792
11793   if (is_add == -1)
11794     {
11795       errmsg ("expecting: add|del");
11796       return -99;
11797     }
11798   if (classify_table_index == ~0)
11799     {
11800       errmsg ("classifier table not specified");
11801       return -99;
11802     }
11803   if (ip_version == 0)
11804     {
11805       errmsg ("IP version not specified");
11806       return -99;
11807     }
11808
11809   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11810
11811   mp->is_add = is_add;
11812   mp->table_id = htonl (classify_table_index);
11813   mp->ip_version = ip_version;
11814   mp->transport_protocol = transport_protocol;
11815
11816   S (mp);
11817   W (ret);
11818   return ret;
11819 }
11820
11821 static int
11822 api_get_node_index (vat_main_t * vam)
11823 {
11824   unformat_input_t *i = vam->input;
11825   vl_api_get_node_index_t *mp;
11826   u8 *name = 0;
11827   int ret;
11828
11829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11830     {
11831       if (unformat (i, "node %s", &name))
11832         ;
11833       else
11834         break;
11835     }
11836   if (name == 0)
11837     {
11838       errmsg ("node name required");
11839       return -99;
11840     }
11841   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11842     {
11843       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11844       return -99;
11845     }
11846
11847   M (GET_NODE_INDEX, mp);
11848   clib_memcpy (mp->node_name, name, vec_len (name));
11849   vec_free (name);
11850
11851   S (mp);
11852   W (ret);
11853   return ret;
11854 }
11855
11856 static int
11857 api_get_next_index (vat_main_t * vam)
11858 {
11859   unformat_input_t *i = vam->input;
11860   vl_api_get_next_index_t *mp;
11861   u8 *node_name = 0, *next_node_name = 0;
11862   int ret;
11863
11864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11865     {
11866       if (unformat (i, "node-name %s", &node_name))
11867         ;
11868       else if (unformat (i, "next-node-name %s", &next_node_name))
11869         break;
11870     }
11871
11872   if (node_name == 0)
11873     {
11874       errmsg ("node name required");
11875       return -99;
11876     }
11877   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11878     {
11879       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11880       return -99;
11881     }
11882
11883   if (next_node_name == 0)
11884     {
11885       errmsg ("next node name required");
11886       return -99;
11887     }
11888   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11889     {
11890       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11891       return -99;
11892     }
11893
11894   M (GET_NEXT_INDEX, mp);
11895   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11896   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11897   vec_free (node_name);
11898   vec_free (next_node_name);
11899
11900   S (mp);
11901   W (ret);
11902   return ret;
11903 }
11904
11905 static int
11906 api_add_node_next (vat_main_t * vam)
11907 {
11908   unformat_input_t *i = vam->input;
11909   vl_api_add_node_next_t *mp;
11910   u8 *name = 0;
11911   u8 *next = 0;
11912   int ret;
11913
11914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (i, "node %s", &name))
11917         ;
11918       else if (unformat (i, "next %s", &next))
11919         ;
11920       else
11921         break;
11922     }
11923   if (name == 0)
11924     {
11925       errmsg ("node name required");
11926       return -99;
11927     }
11928   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11929     {
11930       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11931       return -99;
11932     }
11933   if (next == 0)
11934     {
11935       errmsg ("next node required");
11936       return -99;
11937     }
11938   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11939     {
11940       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11941       return -99;
11942     }
11943
11944   M (ADD_NODE_NEXT, mp);
11945   clib_memcpy (mp->node_name, name, vec_len (name));
11946   clib_memcpy (mp->next_name, next, vec_len (next));
11947   vec_free (name);
11948   vec_free (next);
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static int
11956 api_l2tpv3_create_tunnel (vat_main_t * vam)
11957 {
11958   unformat_input_t *i = vam->input;
11959   ip6_address_t client_address, our_address;
11960   int client_address_set = 0;
11961   int our_address_set = 0;
11962   u32 local_session_id = 0;
11963   u32 remote_session_id = 0;
11964   u64 local_cookie = 0;
11965   u64 remote_cookie = 0;
11966   u8 l2_sublayer_present = 0;
11967   vl_api_l2tpv3_create_tunnel_t *mp;
11968   int ret;
11969
11970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11971     {
11972       if (unformat (i, "client_address %U", unformat_ip6_address,
11973                     &client_address))
11974         client_address_set = 1;
11975       else if (unformat (i, "our_address %U", unformat_ip6_address,
11976                          &our_address))
11977         our_address_set = 1;
11978       else if (unformat (i, "local_session_id %d", &local_session_id))
11979         ;
11980       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11981         ;
11982       else if (unformat (i, "local_cookie %lld", &local_cookie))
11983         ;
11984       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11985         ;
11986       else if (unformat (i, "l2-sublayer-present"))
11987         l2_sublayer_present = 1;
11988       else
11989         break;
11990     }
11991
11992   if (client_address_set == 0)
11993     {
11994       errmsg ("client_address required");
11995       return -99;
11996     }
11997
11998   if (our_address_set == 0)
11999     {
12000       errmsg ("our_address required");
12001       return -99;
12002     }
12003
12004   M (L2TPV3_CREATE_TUNNEL, mp);
12005
12006   clib_memcpy (mp->client_address, client_address.as_u8,
12007                sizeof (mp->client_address));
12008
12009   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12010
12011   mp->local_session_id = ntohl (local_session_id);
12012   mp->remote_session_id = ntohl (remote_session_id);
12013   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12014   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12015   mp->l2_sublayer_present = l2_sublayer_present;
12016   mp->is_ipv6 = 1;
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static int
12024 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12025 {
12026   unformat_input_t *i = vam->input;
12027   u32 sw_if_index;
12028   u8 sw_if_index_set = 0;
12029   u64 new_local_cookie = 0;
12030   u64 new_remote_cookie = 0;
12031   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12032   int ret;
12033
12034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12035     {
12036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12037         sw_if_index_set = 1;
12038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12039         sw_if_index_set = 1;
12040       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12041         ;
12042       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12043         ;
12044       else
12045         break;
12046     }
12047
12048   if (sw_if_index_set == 0)
12049     {
12050       errmsg ("missing interface name or sw_if_index");
12051       return -99;
12052     }
12053
12054   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12055
12056   mp->sw_if_index = ntohl (sw_if_index);
12057   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12058   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12059
12060   S (mp);
12061   W (ret);
12062   return ret;
12063 }
12064
12065 static int
12066 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12067 {
12068   unformat_input_t *i = vam->input;
12069   vl_api_l2tpv3_interface_enable_disable_t *mp;
12070   u32 sw_if_index;
12071   u8 sw_if_index_set = 0;
12072   u8 enable_disable = 1;
12073   int ret;
12074
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12078         sw_if_index_set = 1;
12079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12080         sw_if_index_set = 1;
12081       else if (unformat (i, "enable"))
12082         enable_disable = 1;
12083       else if (unformat (i, "disable"))
12084         enable_disable = 0;
12085       else
12086         break;
12087     }
12088
12089   if (sw_if_index_set == 0)
12090     {
12091       errmsg ("missing interface name or sw_if_index");
12092       return -99;
12093     }
12094
12095   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12096
12097   mp->sw_if_index = ntohl (sw_if_index);
12098   mp->enable_disable = enable_disable;
12099
12100   S (mp);
12101   W (ret);
12102   return ret;
12103 }
12104
12105 static int
12106 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12107 {
12108   unformat_input_t *i = vam->input;
12109   vl_api_l2tpv3_set_lookup_key_t *mp;
12110   u8 key = ~0;
12111   int ret;
12112
12113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12114     {
12115       if (unformat (i, "lookup_v6_src"))
12116         key = L2T_LOOKUP_SRC_ADDRESS;
12117       else if (unformat (i, "lookup_v6_dst"))
12118         key = L2T_LOOKUP_DST_ADDRESS;
12119       else if (unformat (i, "lookup_session_id"))
12120         key = L2T_LOOKUP_SESSION_ID;
12121       else
12122         break;
12123     }
12124
12125   if (key == (u8) ~ 0)
12126     {
12127       errmsg ("l2tp session lookup key unset");
12128       return -99;
12129     }
12130
12131   M (L2TPV3_SET_LOOKUP_KEY, mp);
12132
12133   mp->key = key;
12134
12135   S (mp);
12136   W (ret);
12137   return ret;
12138 }
12139
12140 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12141   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12142 {
12143   vat_main_t *vam = &vat_main;
12144
12145   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12146          format_ip6_address, mp->our_address,
12147          format_ip6_address, mp->client_address,
12148          clib_net_to_host_u32 (mp->sw_if_index));
12149
12150   print (vam->ofp,
12151          "   local cookies %016llx %016llx remote cookie %016llx",
12152          clib_net_to_host_u64 (mp->local_cookie[0]),
12153          clib_net_to_host_u64 (mp->local_cookie[1]),
12154          clib_net_to_host_u64 (mp->remote_cookie));
12155
12156   print (vam->ofp, "   local session-id %d remote session-id %d",
12157          clib_net_to_host_u32 (mp->local_session_id),
12158          clib_net_to_host_u32 (mp->remote_session_id));
12159
12160   print (vam->ofp, "   l2 specific sublayer %s\n",
12161          mp->l2_sublayer_present ? "preset" : "absent");
12162
12163 }
12164
12165 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12166   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12167 {
12168   vat_main_t *vam = &vat_main;
12169   vat_json_node_t *node = NULL;
12170   struct in6_addr addr;
12171
12172   if (VAT_JSON_ARRAY != vam->json_tree.type)
12173     {
12174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12175       vat_json_init_array (&vam->json_tree);
12176     }
12177   node = vat_json_array_add (&vam->json_tree);
12178
12179   vat_json_init_object (node);
12180
12181   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12182   vat_json_object_add_ip6 (node, "our_address", addr);
12183   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12184   vat_json_object_add_ip6 (node, "client_address", addr);
12185
12186   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12187   vat_json_init_array (lc);
12188   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12189   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12190   vat_json_object_add_uint (node, "remote_cookie",
12191                             clib_net_to_host_u64 (mp->remote_cookie));
12192
12193   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12194   vat_json_object_add_uint (node, "local_session_id",
12195                             clib_net_to_host_u32 (mp->local_session_id));
12196   vat_json_object_add_uint (node, "remote_session_id",
12197                             clib_net_to_host_u32 (mp->remote_session_id));
12198   vat_json_object_add_string_copy (node, "l2_sublayer",
12199                                    mp->l2_sublayer_present ? (u8 *) "present"
12200                                    : (u8 *) "absent");
12201 }
12202
12203 static int
12204 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12205 {
12206   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12207   vl_api_control_ping_t *mp_ping;
12208   int ret;
12209
12210   /* Get list of l2tpv3-tunnel interfaces */
12211   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12212   S (mp);
12213
12214   /* Use a control ping for synchronization */
12215   MPING (CONTROL_PING, mp_ping);
12216   S (mp_ping);
12217
12218   W (ret);
12219   return ret;
12220 }
12221
12222
12223 static void vl_api_sw_interface_tap_v2_details_t_handler
12224   (vl_api_sw_interface_tap_v2_details_t * mp)
12225 {
12226   vat_main_t *vam = &vat_main;
12227
12228   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12229                     mp->host_ip4_prefix_len);
12230   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12231                     mp->host_ip6_prefix_len);
12232
12233   print (vam->ofp,
12234          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12235          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12236          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12237          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12238          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12239
12240   vec_free (ip4);
12241   vec_free (ip6);
12242 }
12243
12244 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12245   (vl_api_sw_interface_tap_v2_details_t * mp)
12246 {
12247   vat_main_t *vam = &vat_main;
12248   vat_json_node_t *node = NULL;
12249
12250   if (VAT_JSON_ARRAY != vam->json_tree.type)
12251     {
12252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12253       vat_json_init_array (&vam->json_tree);
12254     }
12255   node = vat_json_array_add (&vam->json_tree);
12256
12257   vat_json_init_object (node);
12258   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12259   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12260   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12261   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12262   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12263   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12264   vat_json_object_add_string_copy (node, "host_mac_addr",
12265                                    format (0, "%U", format_ethernet_address,
12266                                            &mp->host_mac_addr));
12267   vat_json_object_add_string_copy (node, "host_namespace",
12268                                    mp->host_namespace);
12269   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12270   vat_json_object_add_string_copy (node, "host_ip4_addr",
12271                                    format (0, "%U/%d", format_ip4_address,
12272                                            mp->host_ip4_addr,
12273                                            mp->host_ip4_prefix_len));
12274   vat_json_object_add_string_copy (node, "host_ip6_addr",
12275                                    format (0, "%U/%d", format_ip6_address,
12276                                            mp->host_ip6_addr,
12277                                            mp->host_ip6_prefix_len));
12278
12279 }
12280
12281 static int
12282 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12283 {
12284   vl_api_sw_interface_tap_v2_dump_t *mp;
12285   vl_api_control_ping_t *mp_ping;
12286   int ret;
12287
12288   print (vam->ofp,
12289          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12290          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12291          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12292          "host_ip6_addr");
12293
12294   /* Get list of tap interfaces */
12295   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12296   S (mp);
12297
12298   /* Use a control ping for synchronization */
12299   MPING (CONTROL_PING, mp_ping);
12300   S (mp_ping);
12301
12302   W (ret);
12303   return ret;
12304 }
12305
12306 static void vl_api_sw_interface_virtio_pci_details_t_handler
12307   (vl_api_sw_interface_virtio_pci_details_t * mp)
12308 {
12309   vat_main_t *vam = &vat_main;
12310
12311   typedef union
12312   {
12313     struct
12314     {
12315       u16 domain;
12316       u8 bus;
12317       u8 slot:5;
12318       u8 function:3;
12319     };
12320     u32 as_u32;
12321   } pci_addr_t;
12322   pci_addr_t addr;
12323   addr.as_u32 = ntohl (mp->pci_addr);
12324   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12325                          addr.slot, addr.function);
12326
12327   print (vam->ofp,
12328          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12329          pci_addr, ntohl (mp->sw_if_index),
12330          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12331          format_ethernet_address, mp->mac_addr,
12332          clib_net_to_host_u64 (mp->features));
12333   vec_free (pci_addr);
12334 }
12335
12336 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12337   (vl_api_sw_interface_virtio_pci_details_t * mp)
12338 {
12339   vat_main_t *vam = &vat_main;
12340   vat_json_node_t *node = NULL;
12341
12342   if (VAT_JSON_ARRAY != vam->json_tree.type)
12343     {
12344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12345       vat_json_init_array (&vam->json_tree);
12346     }
12347   node = vat_json_array_add (&vam->json_tree);
12348
12349   vat_json_init_object (node);
12350   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12351   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12352   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12353   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12354   vat_json_object_add_uint (node, "features",
12355                             clib_net_to_host_u64 (mp->features));
12356   vat_json_object_add_string_copy (node, "mac_addr",
12357                                    format (0, "%U", format_ethernet_address,
12358                                            &mp->mac_addr));
12359 }
12360
12361 static int
12362 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12363 {
12364   vl_api_sw_interface_virtio_pci_dump_t *mp;
12365   vl_api_control_ping_t *mp_ping;
12366   int ret;
12367
12368   print (vam->ofp,
12369          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12370          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12371          "mac_addr", "features");
12372
12373   /* Get list of tap interfaces */
12374   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12375   S (mp);
12376
12377   /* Use a control ping for synchronization */
12378   MPING (CONTROL_PING, mp_ping);
12379   S (mp_ping);
12380
12381   W (ret);
12382   return ret;
12383 }
12384
12385 static int
12386 api_vxlan_offload_rx (vat_main_t * vam)
12387 {
12388   unformat_input_t *line_input = vam->input;
12389   vl_api_vxlan_offload_rx_t *mp;
12390   u32 hw_if_index = ~0, rx_if_index = ~0;
12391   u8 is_add = 1;
12392   int ret;
12393
12394   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12395     {
12396       if (unformat (line_input, "del"))
12397         is_add = 0;
12398       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12399                          &hw_if_index))
12400         ;
12401       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12402         ;
12403       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12404                          &rx_if_index))
12405         ;
12406       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12407         ;
12408       else
12409         {
12410           errmsg ("parse error '%U'", format_unformat_error, line_input);
12411           return -99;
12412         }
12413     }
12414
12415   if (hw_if_index == ~0)
12416     {
12417       errmsg ("no hw interface");
12418       return -99;
12419     }
12420
12421   if (rx_if_index == ~0)
12422     {
12423       errmsg ("no rx tunnel");
12424       return -99;
12425     }
12426
12427   M (VXLAN_OFFLOAD_RX, mp);
12428
12429   mp->hw_if_index = ntohl (hw_if_index);
12430   mp->sw_if_index = ntohl (rx_if_index);
12431   mp->enable = is_add;
12432
12433   S (mp);
12434   W (ret);
12435   return ret;
12436 }
12437
12438 static uword unformat_vxlan_decap_next
12439   (unformat_input_t * input, va_list * args)
12440 {
12441   u32 *result = va_arg (*args, u32 *);
12442   u32 tmp;
12443
12444   if (unformat (input, "l2"))
12445     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12446   else if (unformat (input, "%d", &tmp))
12447     *result = tmp;
12448   else
12449     return 0;
12450   return 1;
12451 }
12452
12453 static int
12454 api_vxlan_add_del_tunnel (vat_main_t * vam)
12455 {
12456   unformat_input_t *line_input = vam->input;
12457   vl_api_vxlan_add_del_tunnel_t *mp;
12458   ip46_address_t src, dst;
12459   u8 is_add = 1;
12460   u8 ipv4_set = 0, ipv6_set = 0;
12461   u8 src_set = 0;
12462   u8 dst_set = 0;
12463   u8 grp_set = 0;
12464   u32 instance = ~0;
12465   u32 mcast_sw_if_index = ~0;
12466   u32 encap_vrf_id = 0;
12467   u32 decap_next_index = ~0;
12468   u32 vni = 0;
12469   int ret;
12470
12471   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12472   clib_memset (&src, 0, sizeof src);
12473   clib_memset (&dst, 0, sizeof dst);
12474
12475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12476     {
12477       if (unformat (line_input, "del"))
12478         is_add = 0;
12479       else if (unformat (line_input, "instance %d", &instance))
12480         ;
12481       else
12482         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12483         {
12484           ipv4_set = 1;
12485           src_set = 1;
12486         }
12487       else
12488         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12489         {
12490           ipv4_set = 1;
12491           dst_set = 1;
12492         }
12493       else
12494         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12495         {
12496           ipv6_set = 1;
12497           src_set = 1;
12498         }
12499       else
12500         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12501         {
12502           ipv6_set = 1;
12503           dst_set = 1;
12504         }
12505       else if (unformat (line_input, "group %U %U",
12506                          unformat_ip4_address, &dst.ip4,
12507                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12508         {
12509           grp_set = dst_set = 1;
12510           ipv4_set = 1;
12511         }
12512       else if (unformat (line_input, "group %U",
12513                          unformat_ip4_address, &dst.ip4))
12514         {
12515           grp_set = dst_set = 1;
12516           ipv4_set = 1;
12517         }
12518       else if (unformat (line_input, "group %U %U",
12519                          unformat_ip6_address, &dst.ip6,
12520                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12521         {
12522           grp_set = dst_set = 1;
12523           ipv6_set = 1;
12524         }
12525       else if (unformat (line_input, "group %U",
12526                          unformat_ip6_address, &dst.ip6))
12527         {
12528           grp_set = dst_set = 1;
12529           ipv6_set = 1;
12530         }
12531       else
12532         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12533         ;
12534       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12535         ;
12536       else if (unformat (line_input, "decap-next %U",
12537                          unformat_vxlan_decap_next, &decap_next_index))
12538         ;
12539       else if (unformat (line_input, "vni %d", &vni))
12540         ;
12541       else
12542         {
12543           errmsg ("parse error '%U'", format_unformat_error, line_input);
12544           return -99;
12545         }
12546     }
12547
12548   if (src_set == 0)
12549     {
12550       errmsg ("tunnel src address not specified");
12551       return -99;
12552     }
12553   if (dst_set == 0)
12554     {
12555       errmsg ("tunnel dst address not specified");
12556       return -99;
12557     }
12558
12559   if (grp_set && !ip46_address_is_multicast (&dst))
12560     {
12561       errmsg ("tunnel group address not multicast");
12562       return -99;
12563     }
12564   if (grp_set && mcast_sw_if_index == ~0)
12565     {
12566       errmsg ("tunnel nonexistent multicast device");
12567       return -99;
12568     }
12569   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12570     {
12571       errmsg ("tunnel dst address must be unicast");
12572       return -99;
12573     }
12574
12575
12576   if (ipv4_set && ipv6_set)
12577     {
12578       errmsg ("both IPv4 and IPv6 addresses specified");
12579       return -99;
12580     }
12581
12582   if ((vni == 0) || (vni >> 24))
12583     {
12584       errmsg ("vni not specified or out of range");
12585       return -99;
12586     }
12587
12588   M (VXLAN_ADD_DEL_TUNNEL, mp);
12589
12590   if (ipv6_set)
12591     {
12592       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12593       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12594     }
12595   else
12596     {
12597       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12598       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12599     }
12600
12601   mp->instance = htonl (instance);
12602   mp->encap_vrf_id = ntohl (encap_vrf_id);
12603   mp->decap_next_index = ntohl (decap_next_index);
12604   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12605   mp->vni = ntohl (vni);
12606   mp->is_add = is_add;
12607   mp->is_ipv6 = ipv6_set;
12608
12609   S (mp);
12610   W (ret);
12611   return ret;
12612 }
12613
12614 static void vl_api_vxlan_tunnel_details_t_handler
12615   (vl_api_vxlan_tunnel_details_t * mp)
12616 {
12617   vat_main_t *vam = &vat_main;
12618   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12619   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12620
12621   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12622          ntohl (mp->sw_if_index),
12623          ntohl (mp->instance),
12624          format_ip46_address, &src, IP46_TYPE_ANY,
12625          format_ip46_address, &dst, IP46_TYPE_ANY,
12626          ntohl (mp->encap_vrf_id),
12627          ntohl (mp->decap_next_index), ntohl (mp->vni),
12628          ntohl (mp->mcast_sw_if_index));
12629 }
12630
12631 static void vl_api_vxlan_tunnel_details_t_handler_json
12632   (vl_api_vxlan_tunnel_details_t * mp)
12633 {
12634   vat_main_t *vam = &vat_main;
12635   vat_json_node_t *node = NULL;
12636
12637   if (VAT_JSON_ARRAY != vam->json_tree.type)
12638     {
12639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12640       vat_json_init_array (&vam->json_tree);
12641     }
12642   node = vat_json_array_add (&vam->json_tree);
12643
12644   vat_json_init_object (node);
12645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12646
12647   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12648
12649   if (mp->is_ipv6)
12650     {
12651       struct in6_addr ip6;
12652
12653       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12654       vat_json_object_add_ip6 (node, "src_address", ip6);
12655       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12656       vat_json_object_add_ip6 (node, "dst_address", ip6);
12657     }
12658   else
12659     {
12660       struct in_addr ip4;
12661
12662       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12663       vat_json_object_add_ip4 (node, "src_address", ip4);
12664       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12665       vat_json_object_add_ip4 (node, "dst_address", ip4);
12666     }
12667   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12668   vat_json_object_add_uint (node, "decap_next_index",
12669                             ntohl (mp->decap_next_index));
12670   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12671   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12672   vat_json_object_add_uint (node, "mcast_sw_if_index",
12673                             ntohl (mp->mcast_sw_if_index));
12674 }
12675
12676 static int
12677 api_vxlan_tunnel_dump (vat_main_t * vam)
12678 {
12679   unformat_input_t *i = vam->input;
12680   vl_api_vxlan_tunnel_dump_t *mp;
12681   vl_api_control_ping_t *mp_ping;
12682   u32 sw_if_index;
12683   u8 sw_if_index_set = 0;
12684   int ret;
12685
12686   /* Parse args required to build the message */
12687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12688     {
12689       if (unformat (i, "sw_if_index %d", &sw_if_index))
12690         sw_if_index_set = 1;
12691       else
12692         break;
12693     }
12694
12695   if (sw_if_index_set == 0)
12696     {
12697       sw_if_index = ~0;
12698     }
12699
12700   if (!vam->json_output)
12701     {
12702       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12703              "sw_if_index", "instance", "src_address", "dst_address",
12704              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12705     }
12706
12707   /* Get list of vxlan-tunnel interfaces */
12708   M (VXLAN_TUNNEL_DUMP, mp);
12709
12710   mp->sw_if_index = htonl (sw_if_index);
12711
12712   S (mp);
12713
12714   /* Use a control ping for synchronization */
12715   MPING (CONTROL_PING, mp_ping);
12716   S (mp_ping);
12717
12718   W (ret);
12719   return ret;
12720 }
12721
12722 static uword unformat_geneve_decap_next
12723   (unformat_input_t * input, va_list * args)
12724 {
12725   u32 *result = va_arg (*args, u32 *);
12726   u32 tmp;
12727
12728   if (unformat (input, "l2"))
12729     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12730   else if (unformat (input, "%d", &tmp))
12731     *result = tmp;
12732   else
12733     return 0;
12734   return 1;
12735 }
12736
12737 static int
12738 api_geneve_add_del_tunnel (vat_main_t * vam)
12739 {
12740   unformat_input_t *line_input = vam->input;
12741   vl_api_geneve_add_del_tunnel_t *mp;
12742   ip46_address_t src, dst;
12743   u8 is_add = 1;
12744   u8 ipv4_set = 0, ipv6_set = 0;
12745   u8 src_set = 0;
12746   u8 dst_set = 0;
12747   u8 grp_set = 0;
12748   u32 mcast_sw_if_index = ~0;
12749   u32 encap_vrf_id = 0;
12750   u32 decap_next_index = ~0;
12751   u32 vni = 0;
12752   int ret;
12753
12754   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12755   clib_memset (&src, 0, sizeof src);
12756   clib_memset (&dst, 0, sizeof dst);
12757
12758   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12759     {
12760       if (unformat (line_input, "del"))
12761         is_add = 0;
12762       else
12763         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12764         {
12765           ipv4_set = 1;
12766           src_set = 1;
12767         }
12768       else
12769         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12770         {
12771           ipv4_set = 1;
12772           dst_set = 1;
12773         }
12774       else
12775         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12776         {
12777           ipv6_set = 1;
12778           src_set = 1;
12779         }
12780       else
12781         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12782         {
12783           ipv6_set = 1;
12784           dst_set = 1;
12785         }
12786       else if (unformat (line_input, "group %U %U",
12787                          unformat_ip4_address, &dst.ip4,
12788                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12789         {
12790           grp_set = dst_set = 1;
12791           ipv4_set = 1;
12792         }
12793       else if (unformat (line_input, "group %U",
12794                          unformat_ip4_address, &dst.ip4))
12795         {
12796           grp_set = dst_set = 1;
12797           ipv4_set = 1;
12798         }
12799       else if (unformat (line_input, "group %U %U",
12800                          unformat_ip6_address, &dst.ip6,
12801                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12802         {
12803           grp_set = dst_set = 1;
12804           ipv6_set = 1;
12805         }
12806       else if (unformat (line_input, "group %U",
12807                          unformat_ip6_address, &dst.ip6))
12808         {
12809           grp_set = dst_set = 1;
12810           ipv6_set = 1;
12811         }
12812       else
12813         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12814         ;
12815       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12816         ;
12817       else if (unformat (line_input, "decap-next %U",
12818                          unformat_geneve_decap_next, &decap_next_index))
12819         ;
12820       else if (unformat (line_input, "vni %d", &vni))
12821         ;
12822       else
12823         {
12824           errmsg ("parse error '%U'", format_unformat_error, line_input);
12825           return -99;
12826         }
12827     }
12828
12829   if (src_set == 0)
12830     {
12831       errmsg ("tunnel src address not specified");
12832       return -99;
12833     }
12834   if (dst_set == 0)
12835     {
12836       errmsg ("tunnel dst address not specified");
12837       return -99;
12838     }
12839
12840   if (grp_set && !ip46_address_is_multicast (&dst))
12841     {
12842       errmsg ("tunnel group address not multicast");
12843       return -99;
12844     }
12845   if (grp_set && mcast_sw_if_index == ~0)
12846     {
12847       errmsg ("tunnel nonexistent multicast device");
12848       return -99;
12849     }
12850   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12851     {
12852       errmsg ("tunnel dst address must be unicast");
12853       return -99;
12854     }
12855
12856
12857   if (ipv4_set && ipv6_set)
12858     {
12859       errmsg ("both IPv4 and IPv6 addresses specified");
12860       return -99;
12861     }
12862
12863   if ((vni == 0) || (vni >> 24))
12864     {
12865       errmsg ("vni not specified or out of range");
12866       return -99;
12867     }
12868
12869   M (GENEVE_ADD_DEL_TUNNEL, mp);
12870
12871   if (ipv6_set)
12872     {
12873       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12874       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12875     }
12876   else
12877     {
12878       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12879       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12880     }
12881   mp->encap_vrf_id = ntohl (encap_vrf_id);
12882   mp->decap_next_index = ntohl (decap_next_index);
12883   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12884   mp->vni = ntohl (vni);
12885   mp->is_add = is_add;
12886   mp->is_ipv6 = ipv6_set;
12887
12888   S (mp);
12889   W (ret);
12890   return ret;
12891 }
12892
12893 static void vl_api_geneve_tunnel_details_t_handler
12894   (vl_api_geneve_tunnel_details_t * mp)
12895 {
12896   vat_main_t *vam = &vat_main;
12897   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12898   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12899
12900   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12901          ntohl (mp->sw_if_index),
12902          format_ip46_address, &src, IP46_TYPE_ANY,
12903          format_ip46_address, &dst, IP46_TYPE_ANY,
12904          ntohl (mp->encap_vrf_id),
12905          ntohl (mp->decap_next_index), ntohl (mp->vni),
12906          ntohl (mp->mcast_sw_if_index));
12907 }
12908
12909 static void vl_api_geneve_tunnel_details_t_handler_json
12910   (vl_api_geneve_tunnel_details_t * mp)
12911 {
12912   vat_main_t *vam = &vat_main;
12913   vat_json_node_t *node = NULL;
12914
12915   if (VAT_JSON_ARRAY != vam->json_tree.type)
12916     {
12917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12918       vat_json_init_array (&vam->json_tree);
12919     }
12920   node = vat_json_array_add (&vam->json_tree);
12921
12922   vat_json_init_object (node);
12923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12924   if (mp->is_ipv6)
12925     {
12926       struct in6_addr ip6;
12927
12928       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12929       vat_json_object_add_ip6 (node, "src_address", ip6);
12930       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12931       vat_json_object_add_ip6 (node, "dst_address", ip6);
12932     }
12933   else
12934     {
12935       struct in_addr ip4;
12936
12937       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12938       vat_json_object_add_ip4 (node, "src_address", ip4);
12939       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12940       vat_json_object_add_ip4 (node, "dst_address", ip4);
12941     }
12942   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12943   vat_json_object_add_uint (node, "decap_next_index",
12944                             ntohl (mp->decap_next_index));
12945   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12946   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12947   vat_json_object_add_uint (node, "mcast_sw_if_index",
12948                             ntohl (mp->mcast_sw_if_index));
12949 }
12950
12951 static int
12952 api_geneve_tunnel_dump (vat_main_t * vam)
12953 {
12954   unformat_input_t *i = vam->input;
12955   vl_api_geneve_tunnel_dump_t *mp;
12956   vl_api_control_ping_t *mp_ping;
12957   u32 sw_if_index;
12958   u8 sw_if_index_set = 0;
12959   int ret;
12960
12961   /* Parse args required to build the message */
12962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12963     {
12964       if (unformat (i, "sw_if_index %d", &sw_if_index))
12965         sw_if_index_set = 1;
12966       else
12967         break;
12968     }
12969
12970   if (sw_if_index_set == 0)
12971     {
12972       sw_if_index = ~0;
12973     }
12974
12975   if (!vam->json_output)
12976     {
12977       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12978              "sw_if_index", "local_address", "remote_address",
12979              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12980     }
12981
12982   /* Get list of geneve-tunnel interfaces */
12983   M (GENEVE_TUNNEL_DUMP, mp);
12984
12985   mp->sw_if_index = htonl (sw_if_index);
12986
12987   S (mp);
12988
12989   /* Use a control ping for synchronization */
12990   M (CONTROL_PING, mp_ping);
12991   S (mp_ping);
12992
12993   W (ret);
12994   return ret;
12995 }
12996
12997 static int
12998 api_gre_tunnel_add_del (vat_main_t * vam)
12999 {
13000   unformat_input_t *line_input = vam->input;
13001   vl_api_address_t src = { }, dst =
13002   {
13003   };
13004   vl_api_gre_tunnel_add_del_t *mp;
13005   vl_api_gre_tunnel_type_t t_type;
13006   u8 is_add = 1;
13007   u8 src_set = 0;
13008   u8 dst_set = 0;
13009   u32 outer_fib_id = 0;
13010   u32 session_id = 0;
13011   u32 instance = ~0;
13012   int ret;
13013
13014   t_type = GRE_API_TUNNEL_TYPE_L3;
13015
13016   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13017     {
13018       if (unformat (line_input, "del"))
13019         is_add = 0;
13020       else if (unformat (line_input, "instance %d", &instance))
13021         ;
13022       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13023         {
13024           src_set = 1;
13025         }
13026       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13027         {
13028           dst_set = 1;
13029         }
13030       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13031         ;
13032       else if (unformat (line_input, "teb"))
13033         t_type = GRE_API_TUNNEL_TYPE_TEB;
13034       else if (unformat (line_input, "erspan %d", &session_id))
13035         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13036       else
13037         {
13038           errmsg ("parse error '%U'", format_unformat_error, line_input);
13039           return -99;
13040         }
13041     }
13042
13043   if (src_set == 0)
13044     {
13045       errmsg ("tunnel src address not specified");
13046       return -99;
13047     }
13048   if (dst_set == 0)
13049     {
13050       errmsg ("tunnel dst address not specified");
13051       return -99;
13052     }
13053
13054   M (GRE_TUNNEL_ADD_DEL, mp);
13055
13056   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13057   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13058
13059   mp->tunnel.instance = htonl (instance);
13060   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13061   mp->is_add = is_add;
13062   mp->tunnel.session_id = htons ((u16) session_id);
13063   mp->tunnel.type = htonl (t_type);
13064
13065   S (mp);
13066   W (ret);
13067   return ret;
13068 }
13069
13070 static void vl_api_gre_tunnel_details_t_handler
13071   (vl_api_gre_tunnel_details_t * mp)
13072 {
13073   vat_main_t *vam = &vat_main;
13074
13075   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13076          ntohl (mp->tunnel.sw_if_index),
13077          ntohl (mp->tunnel.instance),
13078          format_vl_api_address, &mp->tunnel.src,
13079          format_vl_api_address, &mp->tunnel.dst,
13080          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13081          ntohl (mp->tunnel.session_id));
13082 }
13083
13084 static void vl_api_gre_tunnel_details_t_handler_json
13085   (vl_api_gre_tunnel_details_t * mp)
13086 {
13087   vat_main_t *vam = &vat_main;
13088   vat_json_node_t *node = NULL;
13089
13090   if (VAT_JSON_ARRAY != vam->json_tree.type)
13091     {
13092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13093       vat_json_init_array (&vam->json_tree);
13094     }
13095   node = vat_json_array_add (&vam->json_tree);
13096
13097   vat_json_init_object (node);
13098   vat_json_object_add_uint (node, "sw_if_index",
13099                             ntohl (mp->tunnel.sw_if_index));
13100   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13101
13102   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13103   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13104   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13105   vat_json_object_add_uint (node, "outer_fib_id",
13106                             ntohl (mp->tunnel.outer_fib_id));
13107   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13108 }
13109
13110 static int
13111 api_gre_tunnel_dump (vat_main_t * vam)
13112 {
13113   unformat_input_t *i = vam->input;
13114   vl_api_gre_tunnel_dump_t *mp;
13115   vl_api_control_ping_t *mp_ping;
13116   u32 sw_if_index;
13117   u8 sw_if_index_set = 0;
13118   int ret;
13119
13120   /* Parse args required to build the message */
13121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13122     {
13123       if (unformat (i, "sw_if_index %d", &sw_if_index))
13124         sw_if_index_set = 1;
13125       else
13126         break;
13127     }
13128
13129   if (sw_if_index_set == 0)
13130     {
13131       sw_if_index = ~0;
13132     }
13133
13134   if (!vam->json_output)
13135     {
13136       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13137              "sw_if_index", "instance", "src_address", "dst_address",
13138              "tunnel_type", "outer_fib_id", "session_id");
13139     }
13140
13141   /* Get list of gre-tunnel interfaces */
13142   M (GRE_TUNNEL_DUMP, mp);
13143
13144   mp->sw_if_index = htonl (sw_if_index);
13145
13146   S (mp);
13147
13148   /* Use a control ping for synchronization */
13149   MPING (CONTROL_PING, mp_ping);
13150   S (mp_ping);
13151
13152   W (ret);
13153   return ret;
13154 }
13155
13156 static int
13157 api_l2_fib_clear_table (vat_main_t * vam)
13158 {
13159 //  unformat_input_t * i = vam->input;
13160   vl_api_l2_fib_clear_table_t *mp;
13161   int ret;
13162
13163   M (L2_FIB_CLEAR_TABLE, mp);
13164
13165   S (mp);
13166   W (ret);
13167   return ret;
13168 }
13169
13170 static int
13171 api_l2_interface_efp_filter (vat_main_t * vam)
13172 {
13173   unformat_input_t *i = vam->input;
13174   vl_api_l2_interface_efp_filter_t *mp;
13175   u32 sw_if_index;
13176   u8 enable = 1;
13177   u8 sw_if_index_set = 0;
13178   int ret;
13179
13180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13181     {
13182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13183         sw_if_index_set = 1;
13184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13185         sw_if_index_set = 1;
13186       else if (unformat (i, "enable"))
13187         enable = 1;
13188       else if (unformat (i, "disable"))
13189         enable = 0;
13190       else
13191         {
13192           clib_warning ("parse error '%U'", format_unformat_error, i);
13193           return -99;
13194         }
13195     }
13196
13197   if (sw_if_index_set == 0)
13198     {
13199       errmsg ("missing sw_if_index");
13200       return -99;
13201     }
13202
13203   M (L2_INTERFACE_EFP_FILTER, mp);
13204
13205   mp->sw_if_index = ntohl (sw_if_index);
13206   mp->enable_disable = enable;
13207
13208   S (mp);
13209   W (ret);
13210   return ret;
13211 }
13212
13213 #define foreach_vtr_op                          \
13214 _("disable",  L2_VTR_DISABLED)                  \
13215 _("push-1",  L2_VTR_PUSH_1)                     \
13216 _("push-2",  L2_VTR_PUSH_2)                     \
13217 _("pop-1",  L2_VTR_POP_1)                       \
13218 _("pop-2",  L2_VTR_POP_2)                       \
13219 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13220 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13221 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13222 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13223
13224 static int
13225 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13226 {
13227   unformat_input_t *i = vam->input;
13228   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13229   u32 sw_if_index;
13230   u8 sw_if_index_set = 0;
13231   u8 vtr_op_set = 0;
13232   u32 vtr_op = 0;
13233   u32 push_dot1q = 1;
13234   u32 tag1 = ~0;
13235   u32 tag2 = ~0;
13236   int ret;
13237
13238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13241         sw_if_index_set = 1;
13242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13243         sw_if_index_set = 1;
13244       else if (unformat (i, "vtr_op %d", &vtr_op))
13245         vtr_op_set = 1;
13246 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13247       foreach_vtr_op
13248 #undef _
13249         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13250         ;
13251       else if (unformat (i, "tag1 %d", &tag1))
13252         ;
13253       else if (unformat (i, "tag2 %d", &tag2))
13254         ;
13255       else
13256         {
13257           clib_warning ("parse error '%U'", format_unformat_error, i);
13258           return -99;
13259         }
13260     }
13261
13262   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13263     {
13264       errmsg ("missing vtr operation or sw_if_index");
13265       return -99;
13266     }
13267
13268   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13269   mp->sw_if_index = ntohl (sw_if_index);
13270   mp->vtr_op = ntohl (vtr_op);
13271   mp->push_dot1q = ntohl (push_dot1q);
13272   mp->tag1 = ntohl (tag1);
13273   mp->tag2 = ntohl (tag2);
13274
13275   S (mp);
13276   W (ret);
13277   return ret;
13278 }
13279
13280 static int
13281 api_create_vhost_user_if (vat_main_t * vam)
13282 {
13283   unformat_input_t *i = vam->input;
13284   vl_api_create_vhost_user_if_t *mp;
13285   u8 *file_name;
13286   u8 is_server = 0;
13287   u8 file_name_set = 0;
13288   u32 custom_dev_instance = ~0;
13289   u8 hwaddr[6];
13290   u8 use_custom_mac = 0;
13291   u8 disable_mrg_rxbuf = 0;
13292   u8 disable_indirect_desc = 0;
13293   u8 *tag = 0;
13294   int ret;
13295
13296   /* Shut up coverity */
13297   clib_memset (hwaddr, 0, sizeof (hwaddr));
13298
13299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13300     {
13301       if (unformat (i, "socket %s", &file_name))
13302         {
13303           file_name_set = 1;
13304         }
13305       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13306         ;
13307       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13308         use_custom_mac = 1;
13309       else if (unformat (i, "server"))
13310         is_server = 1;
13311       else if (unformat (i, "disable_mrg_rxbuf"))
13312         disable_mrg_rxbuf = 1;
13313       else if (unformat (i, "disable_indirect_desc"))
13314         disable_indirect_desc = 1;
13315       else if (unformat (i, "tag %s", &tag))
13316         ;
13317       else
13318         break;
13319     }
13320
13321   if (file_name_set == 0)
13322     {
13323       errmsg ("missing socket file name");
13324       return -99;
13325     }
13326
13327   if (vec_len (file_name) > 255)
13328     {
13329       errmsg ("socket file name too long");
13330       return -99;
13331     }
13332   vec_add1 (file_name, 0);
13333
13334   M (CREATE_VHOST_USER_IF, mp);
13335
13336   mp->is_server = is_server;
13337   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13338   mp->disable_indirect_desc = disable_indirect_desc;
13339   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13340   vec_free (file_name);
13341   if (custom_dev_instance != ~0)
13342     {
13343       mp->renumber = 1;
13344       mp->custom_dev_instance = ntohl (custom_dev_instance);
13345     }
13346
13347   mp->use_custom_mac = use_custom_mac;
13348   clib_memcpy (mp->mac_address, hwaddr, 6);
13349   if (tag)
13350     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13351   vec_free (tag);
13352
13353   S (mp);
13354   W (ret);
13355   return ret;
13356 }
13357
13358 static int
13359 api_modify_vhost_user_if (vat_main_t * vam)
13360 {
13361   unformat_input_t *i = vam->input;
13362   vl_api_modify_vhost_user_if_t *mp;
13363   u8 *file_name;
13364   u8 is_server = 0;
13365   u8 file_name_set = 0;
13366   u32 custom_dev_instance = ~0;
13367   u8 sw_if_index_set = 0;
13368   u32 sw_if_index = (u32) ~ 0;
13369   int ret;
13370
13371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13372     {
13373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13374         sw_if_index_set = 1;
13375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13376         sw_if_index_set = 1;
13377       else if (unformat (i, "socket %s", &file_name))
13378         {
13379           file_name_set = 1;
13380         }
13381       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13382         ;
13383       else if (unformat (i, "server"))
13384         is_server = 1;
13385       else
13386         break;
13387     }
13388
13389   if (sw_if_index_set == 0)
13390     {
13391       errmsg ("missing sw_if_index or interface name");
13392       return -99;
13393     }
13394
13395   if (file_name_set == 0)
13396     {
13397       errmsg ("missing socket file name");
13398       return -99;
13399     }
13400
13401   if (vec_len (file_name) > 255)
13402     {
13403       errmsg ("socket file name too long");
13404       return -99;
13405     }
13406   vec_add1 (file_name, 0);
13407
13408   M (MODIFY_VHOST_USER_IF, mp);
13409
13410   mp->sw_if_index = ntohl (sw_if_index);
13411   mp->is_server = is_server;
13412   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13413   vec_free (file_name);
13414   if (custom_dev_instance != ~0)
13415     {
13416       mp->renumber = 1;
13417       mp->custom_dev_instance = ntohl (custom_dev_instance);
13418     }
13419
13420   S (mp);
13421   W (ret);
13422   return ret;
13423 }
13424
13425 static int
13426 api_delete_vhost_user_if (vat_main_t * vam)
13427 {
13428   unformat_input_t *i = vam->input;
13429   vl_api_delete_vhost_user_if_t *mp;
13430   u32 sw_if_index = ~0;
13431   u8 sw_if_index_set = 0;
13432   int ret;
13433
13434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13435     {
13436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13437         sw_if_index_set = 1;
13438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13439         sw_if_index_set = 1;
13440       else
13441         break;
13442     }
13443
13444   if (sw_if_index_set == 0)
13445     {
13446       errmsg ("missing sw_if_index or interface name");
13447       return -99;
13448     }
13449
13450
13451   M (DELETE_VHOST_USER_IF, mp);
13452
13453   mp->sw_if_index = ntohl (sw_if_index);
13454
13455   S (mp);
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static void vl_api_sw_interface_vhost_user_details_t_handler
13461   (vl_api_sw_interface_vhost_user_details_t * mp)
13462 {
13463   vat_main_t *vam = &vat_main;
13464
13465   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13466          (char *) mp->interface_name,
13467          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13468          clib_net_to_host_u64 (mp->features), mp->is_server,
13469          ntohl (mp->num_regions), (char *) mp->sock_filename);
13470   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13471 }
13472
13473 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13474   (vl_api_sw_interface_vhost_user_details_t * mp)
13475 {
13476   vat_main_t *vam = &vat_main;
13477   vat_json_node_t *node = NULL;
13478
13479   if (VAT_JSON_ARRAY != vam->json_tree.type)
13480     {
13481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13482       vat_json_init_array (&vam->json_tree);
13483     }
13484   node = vat_json_array_add (&vam->json_tree);
13485
13486   vat_json_init_object (node);
13487   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13488   vat_json_object_add_string_copy (node, "interface_name",
13489                                    mp->interface_name);
13490   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13491                             ntohl (mp->virtio_net_hdr_sz));
13492   vat_json_object_add_uint (node, "features",
13493                             clib_net_to_host_u64 (mp->features));
13494   vat_json_object_add_uint (node, "is_server", mp->is_server);
13495   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13496   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13497   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13498 }
13499
13500 static int
13501 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13502 {
13503   vl_api_sw_interface_vhost_user_dump_t *mp;
13504   vl_api_control_ping_t *mp_ping;
13505   int ret;
13506   print (vam->ofp,
13507          "Interface name            idx hdr_sz features server regions filename");
13508
13509   /* Get list of vhost-user interfaces */
13510   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13511   S (mp);
13512
13513   /* Use a control ping for synchronization */
13514   MPING (CONTROL_PING, mp_ping);
13515   S (mp_ping);
13516
13517   W (ret);
13518   return ret;
13519 }
13520
13521 static int
13522 api_show_version (vat_main_t * vam)
13523 {
13524   vl_api_show_version_t *mp;
13525   int ret;
13526
13527   M (SHOW_VERSION, mp);
13528
13529   S (mp);
13530   W (ret);
13531   return ret;
13532 }
13533
13534
13535 static int
13536 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13537 {
13538   unformat_input_t *line_input = vam->input;
13539   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13540   ip4_address_t local4, remote4;
13541   ip6_address_t local6, remote6;
13542   u8 is_add = 1;
13543   u8 ipv4_set = 0, ipv6_set = 0;
13544   u8 local_set = 0;
13545   u8 remote_set = 0;
13546   u8 grp_set = 0;
13547   u32 mcast_sw_if_index = ~0;
13548   u32 encap_vrf_id = 0;
13549   u32 decap_vrf_id = 0;
13550   u8 protocol = ~0;
13551   u32 vni;
13552   u8 vni_set = 0;
13553   int ret;
13554
13555   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13556   clib_memset (&local4, 0, sizeof local4);
13557   clib_memset (&remote4, 0, sizeof remote4);
13558   clib_memset (&local6, 0, sizeof local6);
13559   clib_memset (&remote6, 0, sizeof remote6);
13560
13561   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13562     {
13563       if (unformat (line_input, "del"))
13564         is_add = 0;
13565       else if (unformat (line_input, "local %U",
13566                          unformat_ip4_address, &local4))
13567         {
13568           local_set = 1;
13569           ipv4_set = 1;
13570         }
13571       else if (unformat (line_input, "remote %U",
13572                          unformat_ip4_address, &remote4))
13573         {
13574           remote_set = 1;
13575           ipv4_set = 1;
13576         }
13577       else if (unformat (line_input, "local %U",
13578                          unformat_ip6_address, &local6))
13579         {
13580           local_set = 1;
13581           ipv6_set = 1;
13582         }
13583       else if (unformat (line_input, "remote %U",
13584                          unformat_ip6_address, &remote6))
13585         {
13586           remote_set = 1;
13587           ipv6_set = 1;
13588         }
13589       else if (unformat (line_input, "group %U %U",
13590                          unformat_ip4_address, &remote4,
13591                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13592         {
13593           grp_set = remote_set = 1;
13594           ipv4_set = 1;
13595         }
13596       else if (unformat (line_input, "group %U",
13597                          unformat_ip4_address, &remote4))
13598         {
13599           grp_set = remote_set = 1;
13600           ipv4_set = 1;
13601         }
13602       else if (unformat (line_input, "group %U %U",
13603                          unformat_ip6_address, &remote6,
13604                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13605         {
13606           grp_set = remote_set = 1;
13607           ipv6_set = 1;
13608         }
13609       else if (unformat (line_input, "group %U",
13610                          unformat_ip6_address, &remote6))
13611         {
13612           grp_set = remote_set = 1;
13613           ipv6_set = 1;
13614         }
13615       else
13616         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13617         ;
13618       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13619         ;
13620       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13621         ;
13622       else if (unformat (line_input, "vni %d", &vni))
13623         vni_set = 1;
13624       else if (unformat (line_input, "next-ip4"))
13625         protocol = 1;
13626       else if (unformat (line_input, "next-ip6"))
13627         protocol = 2;
13628       else if (unformat (line_input, "next-ethernet"))
13629         protocol = 3;
13630       else if (unformat (line_input, "next-nsh"))
13631         protocol = 4;
13632       else
13633         {
13634           errmsg ("parse error '%U'", format_unformat_error, line_input);
13635           return -99;
13636         }
13637     }
13638
13639   if (local_set == 0)
13640     {
13641       errmsg ("tunnel local address not specified");
13642       return -99;
13643     }
13644   if (remote_set == 0)
13645     {
13646       errmsg ("tunnel remote address not specified");
13647       return -99;
13648     }
13649   if (grp_set && mcast_sw_if_index == ~0)
13650     {
13651       errmsg ("tunnel nonexistent multicast device");
13652       return -99;
13653     }
13654   if (ipv4_set && ipv6_set)
13655     {
13656       errmsg ("both IPv4 and IPv6 addresses specified");
13657       return -99;
13658     }
13659
13660   if (vni_set == 0)
13661     {
13662       errmsg ("vni not specified");
13663       return -99;
13664     }
13665
13666   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13667
13668
13669   if (ipv6_set)
13670     {
13671       clib_memcpy (&mp->local, &local6, sizeof (local6));
13672       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13673     }
13674   else
13675     {
13676       clib_memcpy (&mp->local, &local4, sizeof (local4));
13677       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13678     }
13679
13680   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13681   mp->encap_vrf_id = ntohl (encap_vrf_id);
13682   mp->decap_vrf_id = ntohl (decap_vrf_id);
13683   mp->protocol = protocol;
13684   mp->vni = ntohl (vni);
13685   mp->is_add = is_add;
13686   mp->is_ipv6 = ipv6_set;
13687
13688   S (mp);
13689   W (ret);
13690   return ret;
13691 }
13692
13693 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13694   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13695 {
13696   vat_main_t *vam = &vat_main;
13697   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13698   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13699
13700   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13701          ntohl (mp->sw_if_index),
13702          format_ip46_address, &local, IP46_TYPE_ANY,
13703          format_ip46_address, &remote, IP46_TYPE_ANY,
13704          ntohl (mp->vni), mp->protocol,
13705          ntohl (mp->mcast_sw_if_index),
13706          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13707 }
13708
13709
13710 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13711   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13712 {
13713   vat_main_t *vam = &vat_main;
13714   vat_json_node_t *node = NULL;
13715   struct in_addr ip4;
13716   struct in6_addr ip6;
13717
13718   if (VAT_JSON_ARRAY != vam->json_tree.type)
13719     {
13720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13721       vat_json_init_array (&vam->json_tree);
13722     }
13723   node = vat_json_array_add (&vam->json_tree);
13724
13725   vat_json_init_object (node);
13726   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13727   if (mp->is_ipv6)
13728     {
13729       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13730       vat_json_object_add_ip6 (node, "local", ip6);
13731       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13732       vat_json_object_add_ip6 (node, "remote", ip6);
13733     }
13734   else
13735     {
13736       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13737       vat_json_object_add_ip4 (node, "local", ip4);
13738       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13739       vat_json_object_add_ip4 (node, "remote", ip4);
13740     }
13741   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13742   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13743   vat_json_object_add_uint (node, "mcast_sw_if_index",
13744                             ntohl (mp->mcast_sw_if_index));
13745   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13746   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13747   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13748 }
13749
13750 static int
13751 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13752 {
13753   unformat_input_t *i = vam->input;
13754   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13755   vl_api_control_ping_t *mp_ping;
13756   u32 sw_if_index;
13757   u8 sw_if_index_set = 0;
13758   int ret;
13759
13760   /* Parse args required to build the message */
13761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13762     {
13763       if (unformat (i, "sw_if_index %d", &sw_if_index))
13764         sw_if_index_set = 1;
13765       else
13766         break;
13767     }
13768
13769   if (sw_if_index_set == 0)
13770     {
13771       sw_if_index = ~0;
13772     }
13773
13774   if (!vam->json_output)
13775     {
13776       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13777              "sw_if_index", "local", "remote", "vni",
13778              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13779     }
13780
13781   /* Get list of vxlan-tunnel interfaces */
13782   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13783
13784   mp->sw_if_index = htonl (sw_if_index);
13785
13786   S (mp);
13787
13788   /* Use a control ping for synchronization */
13789   MPING (CONTROL_PING, mp_ping);
13790   S (mp_ping);
13791
13792   W (ret);
13793   return ret;
13794 }
13795
13796 static void vl_api_l2_fib_table_details_t_handler
13797   (vl_api_l2_fib_table_details_t * mp)
13798 {
13799   vat_main_t *vam = &vat_main;
13800
13801   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13802          "       %d       %d     %d",
13803          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13804          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13805          mp->bvi_mac);
13806 }
13807
13808 static void vl_api_l2_fib_table_details_t_handler_json
13809   (vl_api_l2_fib_table_details_t * mp)
13810 {
13811   vat_main_t *vam = &vat_main;
13812   vat_json_node_t *node = NULL;
13813
13814   if (VAT_JSON_ARRAY != vam->json_tree.type)
13815     {
13816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13817       vat_json_init_array (&vam->json_tree);
13818     }
13819   node = vat_json_array_add (&vam->json_tree);
13820
13821   vat_json_init_object (node);
13822   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13823   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13825   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13826   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13827   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13828 }
13829
13830 static int
13831 api_l2_fib_table_dump (vat_main_t * vam)
13832 {
13833   unformat_input_t *i = vam->input;
13834   vl_api_l2_fib_table_dump_t *mp;
13835   vl_api_control_ping_t *mp_ping;
13836   u32 bd_id;
13837   u8 bd_id_set = 0;
13838   int ret;
13839
13840   /* Parse args required to build the message */
13841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13842     {
13843       if (unformat (i, "bd_id %d", &bd_id))
13844         bd_id_set = 1;
13845       else
13846         break;
13847     }
13848
13849   if (bd_id_set == 0)
13850     {
13851       errmsg ("missing bridge domain");
13852       return -99;
13853     }
13854
13855   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13856
13857   /* Get list of l2 fib entries */
13858   M (L2_FIB_TABLE_DUMP, mp);
13859
13860   mp->bd_id = ntohl (bd_id);
13861   S (mp);
13862
13863   /* Use a control ping for synchronization */
13864   MPING (CONTROL_PING, mp_ping);
13865   S (mp_ping);
13866
13867   W (ret);
13868   return ret;
13869 }
13870
13871
13872 static int
13873 api_interface_name_renumber (vat_main_t * vam)
13874 {
13875   unformat_input_t *line_input = vam->input;
13876   vl_api_interface_name_renumber_t *mp;
13877   u32 sw_if_index = ~0;
13878   u32 new_show_dev_instance = ~0;
13879   int ret;
13880
13881   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13882     {
13883       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13884                     &sw_if_index))
13885         ;
13886       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13887         ;
13888       else if (unformat (line_input, "new_show_dev_instance %d",
13889                          &new_show_dev_instance))
13890         ;
13891       else
13892         break;
13893     }
13894
13895   if (sw_if_index == ~0)
13896     {
13897       errmsg ("missing interface name or sw_if_index");
13898       return -99;
13899     }
13900
13901   if (new_show_dev_instance == ~0)
13902     {
13903       errmsg ("missing new_show_dev_instance");
13904       return -99;
13905     }
13906
13907   M (INTERFACE_NAME_RENUMBER, mp);
13908
13909   mp->sw_if_index = ntohl (sw_if_index);
13910   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13911
13912   S (mp);
13913   W (ret);
13914   return ret;
13915 }
13916
13917 static int
13918 api_ip_probe_neighbor (vat_main_t * vam)
13919 {
13920   unformat_input_t *i = vam->input;
13921   vl_api_ip_probe_neighbor_t *mp;
13922   vl_api_address_t dst_adr = { };
13923   u8 int_set = 0;
13924   u8 adr_set = 0;
13925   u32 sw_if_index;
13926   int ret;
13927
13928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13931         int_set = 1;
13932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13933         int_set = 1;
13934       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13935         adr_set = 1;
13936       else
13937         break;
13938     }
13939
13940   if (int_set == 0)
13941     {
13942       errmsg ("missing interface");
13943       return -99;
13944     }
13945
13946   if (adr_set == 0)
13947     {
13948       errmsg ("missing addresses");
13949       return -99;
13950     }
13951
13952   M (IP_PROBE_NEIGHBOR, mp);
13953
13954   mp->sw_if_index = ntohl (sw_if_index);
13955   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13956
13957   S (mp);
13958   W (ret);
13959   return ret;
13960 }
13961
13962 static int
13963 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13964 {
13965   unformat_input_t *i = vam->input;
13966   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13967   u8 mode = IP_SCAN_V46_NEIGHBORS;
13968   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13969   int ret;
13970
13971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13972     {
13973       if (unformat (i, "ip4"))
13974         mode = IP_SCAN_V4_NEIGHBORS;
13975       else if (unformat (i, "ip6"))
13976         mode = IP_SCAN_V6_NEIGHBORS;
13977       if (unformat (i, "both"))
13978         mode = IP_SCAN_V46_NEIGHBORS;
13979       else if (unformat (i, "disable"))
13980         mode = IP_SCAN_DISABLED;
13981       else if (unformat (i, "interval %d", &interval))
13982         ;
13983       else if (unformat (i, "max-time %d", &time))
13984         ;
13985       else if (unformat (i, "max-update %d", &update))
13986         ;
13987       else if (unformat (i, "delay %d", &delay))
13988         ;
13989       else if (unformat (i, "stale %d", &stale))
13990         ;
13991       else
13992         break;
13993     }
13994
13995   if (interval > 255)
13996     {
13997       errmsg ("interval cannot exceed 255 minutes.");
13998       return -99;
13999     }
14000   if (time > 255)
14001     {
14002       errmsg ("max-time cannot exceed 255 usec.");
14003       return -99;
14004     }
14005   if (update > 255)
14006     {
14007       errmsg ("max-update cannot exceed 255.");
14008       return -99;
14009     }
14010   if (delay > 255)
14011     {
14012       errmsg ("delay cannot exceed 255 msec.");
14013       return -99;
14014     }
14015   if (stale > 255)
14016     {
14017       errmsg ("stale cannot exceed 255 minutes.");
14018       return -99;
14019     }
14020
14021   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14022   mp->mode = mode;
14023   mp->scan_interval = interval;
14024   mp->max_proc_time = time;
14025   mp->max_update = update;
14026   mp->scan_int_delay = delay;
14027   mp->stale_threshold = stale;
14028
14029   S (mp);
14030   W (ret);
14031   return ret;
14032 }
14033
14034 static int
14035 api_want_ip4_arp_events (vat_main_t * vam)
14036 {
14037   unformat_input_t *line_input = vam->input;
14038   vl_api_want_ip4_arp_events_t *mp;
14039   ip4_address_t address;
14040   int address_set = 0;
14041   u32 enable_disable = 1;
14042   int ret;
14043
14044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14045     {
14046       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14047         address_set = 1;
14048       else if (unformat (line_input, "del"))
14049         enable_disable = 0;
14050       else
14051         break;
14052     }
14053
14054   if (address_set == 0)
14055     {
14056       errmsg ("missing addresses");
14057       return -99;
14058     }
14059
14060   M (WANT_IP4_ARP_EVENTS, mp);
14061   mp->enable_disable = enable_disable;
14062   mp->pid = htonl (getpid ());
14063   clib_memcpy (mp->ip, &address, sizeof (address));
14064
14065   S (mp);
14066   W (ret);
14067   return ret;
14068 }
14069
14070 static int
14071 api_want_ip6_nd_events (vat_main_t * vam)
14072 {
14073   unformat_input_t *line_input = vam->input;
14074   vl_api_want_ip6_nd_events_t *mp;
14075   vl_api_ip6_address_t address;
14076   int address_set = 0;
14077   u32 enable_disable = 1;
14078   int ret;
14079
14080   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat
14083           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14084         address_set = 1;
14085       else if (unformat (line_input, "del"))
14086         enable_disable = 0;
14087       else
14088         break;
14089     }
14090
14091   if (address_set == 0)
14092     {
14093       errmsg ("missing addresses");
14094       return -99;
14095     }
14096
14097   M (WANT_IP6_ND_EVENTS, mp);
14098   mp->enable_disable = enable_disable;
14099   mp->pid = htonl (getpid ());
14100   clib_memcpy (&mp->ip, &address, sizeof (address));
14101
14102   S (mp);
14103   W (ret);
14104   return ret;
14105 }
14106
14107 static int
14108 api_want_l2_macs_events (vat_main_t * vam)
14109 {
14110   unformat_input_t *line_input = vam->input;
14111   vl_api_want_l2_macs_events_t *mp;
14112   u8 enable_disable = 1;
14113   u32 scan_delay = 0;
14114   u32 max_macs_in_event = 0;
14115   u32 learn_limit = 0;
14116   int ret;
14117
14118   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14119     {
14120       if (unformat (line_input, "learn-limit %d", &learn_limit))
14121         ;
14122       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14123         ;
14124       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14125         ;
14126       else if (unformat (line_input, "disable"))
14127         enable_disable = 0;
14128       else
14129         break;
14130     }
14131
14132   M (WANT_L2_MACS_EVENTS, mp);
14133   mp->enable_disable = enable_disable;
14134   mp->pid = htonl (getpid ());
14135   mp->learn_limit = htonl (learn_limit);
14136   mp->scan_delay = (u8) scan_delay;
14137   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14138   S (mp);
14139   W (ret);
14140   return ret;
14141 }
14142
14143 static int
14144 api_input_acl_set_interface (vat_main_t * vam)
14145 {
14146   unformat_input_t *i = vam->input;
14147   vl_api_input_acl_set_interface_t *mp;
14148   u32 sw_if_index;
14149   int sw_if_index_set;
14150   u32 ip4_table_index = ~0;
14151   u32 ip6_table_index = ~0;
14152   u32 l2_table_index = ~0;
14153   u8 is_add = 1;
14154   int ret;
14155
14156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14157     {
14158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14159         sw_if_index_set = 1;
14160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14161         sw_if_index_set = 1;
14162       else if (unformat (i, "del"))
14163         is_add = 0;
14164       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14165         ;
14166       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14167         ;
14168       else if (unformat (i, "l2-table %d", &l2_table_index))
14169         ;
14170       else
14171         {
14172           clib_warning ("parse error '%U'", format_unformat_error, i);
14173           return -99;
14174         }
14175     }
14176
14177   if (sw_if_index_set == 0)
14178     {
14179       errmsg ("missing interface name or sw_if_index");
14180       return -99;
14181     }
14182
14183   M (INPUT_ACL_SET_INTERFACE, mp);
14184
14185   mp->sw_if_index = ntohl (sw_if_index);
14186   mp->ip4_table_index = ntohl (ip4_table_index);
14187   mp->ip6_table_index = ntohl (ip6_table_index);
14188   mp->l2_table_index = ntohl (l2_table_index);
14189   mp->is_add = is_add;
14190
14191   S (mp);
14192   W (ret);
14193   return ret;
14194 }
14195
14196 static int
14197 api_output_acl_set_interface (vat_main_t * vam)
14198 {
14199   unformat_input_t *i = vam->input;
14200   vl_api_output_acl_set_interface_t *mp;
14201   u32 sw_if_index;
14202   int sw_if_index_set;
14203   u32 ip4_table_index = ~0;
14204   u32 ip6_table_index = ~0;
14205   u32 l2_table_index = ~0;
14206   u8 is_add = 1;
14207   int ret;
14208
14209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14210     {
14211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14212         sw_if_index_set = 1;
14213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14214         sw_if_index_set = 1;
14215       else if (unformat (i, "del"))
14216         is_add = 0;
14217       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14218         ;
14219       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14220         ;
14221       else if (unformat (i, "l2-table %d", &l2_table_index))
14222         ;
14223       else
14224         {
14225           clib_warning ("parse error '%U'", format_unformat_error, i);
14226           return -99;
14227         }
14228     }
14229
14230   if (sw_if_index_set == 0)
14231     {
14232       errmsg ("missing interface name or sw_if_index");
14233       return -99;
14234     }
14235
14236   M (OUTPUT_ACL_SET_INTERFACE, mp);
14237
14238   mp->sw_if_index = ntohl (sw_if_index);
14239   mp->ip4_table_index = ntohl (ip4_table_index);
14240   mp->ip6_table_index = ntohl (ip6_table_index);
14241   mp->l2_table_index = ntohl (l2_table_index);
14242   mp->is_add = is_add;
14243
14244   S (mp);
14245   W (ret);
14246   return ret;
14247 }
14248
14249 static int
14250 api_ip_address_dump (vat_main_t * vam)
14251 {
14252   unformat_input_t *i = vam->input;
14253   vl_api_ip_address_dump_t *mp;
14254   vl_api_control_ping_t *mp_ping;
14255   u32 sw_if_index = ~0;
14256   u8 sw_if_index_set = 0;
14257   u8 ipv4_set = 0;
14258   u8 ipv6_set = 0;
14259   int ret;
14260
14261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14262     {
14263       if (unformat (i, "sw_if_index %d", &sw_if_index))
14264         sw_if_index_set = 1;
14265       else
14266         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14267         sw_if_index_set = 1;
14268       else if (unformat (i, "ipv4"))
14269         ipv4_set = 1;
14270       else if (unformat (i, "ipv6"))
14271         ipv6_set = 1;
14272       else
14273         break;
14274     }
14275
14276   if (ipv4_set && ipv6_set)
14277     {
14278       errmsg ("ipv4 and ipv6 flags cannot be both set");
14279       return -99;
14280     }
14281
14282   if ((!ipv4_set) && (!ipv6_set))
14283     {
14284       errmsg ("no ipv4 nor ipv6 flag set");
14285       return -99;
14286     }
14287
14288   if (sw_if_index_set == 0)
14289     {
14290       errmsg ("missing interface name or sw_if_index");
14291       return -99;
14292     }
14293
14294   vam->current_sw_if_index = sw_if_index;
14295   vam->is_ipv6 = ipv6_set;
14296
14297   M (IP_ADDRESS_DUMP, mp);
14298   mp->sw_if_index = ntohl (sw_if_index);
14299   mp->is_ipv6 = ipv6_set;
14300   S (mp);
14301
14302   /* Use a control ping for synchronization */
14303   MPING (CONTROL_PING, mp_ping);
14304   S (mp_ping);
14305
14306   W (ret);
14307   return ret;
14308 }
14309
14310 static int
14311 api_ip_dump (vat_main_t * vam)
14312 {
14313   vl_api_ip_dump_t *mp;
14314   vl_api_control_ping_t *mp_ping;
14315   unformat_input_t *in = vam->input;
14316   int ipv4_set = 0;
14317   int ipv6_set = 0;
14318   int is_ipv6;
14319   int i;
14320   int ret;
14321
14322   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14323     {
14324       if (unformat (in, "ipv4"))
14325         ipv4_set = 1;
14326       else if (unformat (in, "ipv6"))
14327         ipv6_set = 1;
14328       else
14329         break;
14330     }
14331
14332   if (ipv4_set && ipv6_set)
14333     {
14334       errmsg ("ipv4 and ipv6 flags cannot be both set");
14335       return -99;
14336     }
14337
14338   if ((!ipv4_set) && (!ipv6_set))
14339     {
14340       errmsg ("no ipv4 nor ipv6 flag set");
14341       return -99;
14342     }
14343
14344   is_ipv6 = ipv6_set;
14345   vam->is_ipv6 = is_ipv6;
14346
14347   /* free old data */
14348   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14349     {
14350       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14351     }
14352   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14353
14354   M (IP_DUMP, mp);
14355   mp->is_ipv6 = ipv6_set;
14356   S (mp);
14357
14358   /* Use a control ping for synchronization */
14359   MPING (CONTROL_PING, mp_ping);
14360   S (mp_ping);
14361
14362   W (ret);
14363   return ret;
14364 }
14365
14366 static int
14367 api_ipsec_spd_add_del (vat_main_t * vam)
14368 {
14369   unformat_input_t *i = vam->input;
14370   vl_api_ipsec_spd_add_del_t *mp;
14371   u32 spd_id = ~0;
14372   u8 is_add = 1;
14373   int ret;
14374
14375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14376     {
14377       if (unformat (i, "spd_id %d", &spd_id))
14378         ;
14379       else if (unformat (i, "del"))
14380         is_add = 0;
14381       else
14382         {
14383           clib_warning ("parse error '%U'", format_unformat_error, i);
14384           return -99;
14385         }
14386     }
14387   if (spd_id == ~0)
14388     {
14389       errmsg ("spd_id must be set");
14390       return -99;
14391     }
14392
14393   M (IPSEC_SPD_ADD_DEL, mp);
14394
14395   mp->spd_id = ntohl (spd_id);
14396   mp->is_add = is_add;
14397
14398   S (mp);
14399   W (ret);
14400   return ret;
14401 }
14402
14403 static int
14404 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14405 {
14406   unformat_input_t *i = vam->input;
14407   vl_api_ipsec_interface_add_del_spd_t *mp;
14408   u32 sw_if_index;
14409   u8 sw_if_index_set = 0;
14410   u32 spd_id = (u32) ~ 0;
14411   u8 is_add = 1;
14412   int ret;
14413
14414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14415     {
14416       if (unformat (i, "del"))
14417         is_add = 0;
14418       else if (unformat (i, "spd_id %d", &spd_id))
14419         ;
14420       else
14421         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14422         sw_if_index_set = 1;
14423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14424         sw_if_index_set = 1;
14425       else
14426         {
14427           clib_warning ("parse error '%U'", format_unformat_error, i);
14428           return -99;
14429         }
14430
14431     }
14432
14433   if (spd_id == (u32) ~ 0)
14434     {
14435       errmsg ("spd_id must be set");
14436       return -99;
14437     }
14438
14439   if (sw_if_index_set == 0)
14440     {
14441       errmsg ("missing interface name or sw_if_index");
14442       return -99;
14443     }
14444
14445   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14446
14447   mp->spd_id = ntohl (spd_id);
14448   mp->sw_if_index = ntohl (sw_if_index);
14449   mp->is_add = is_add;
14450
14451   S (mp);
14452   W (ret);
14453   return ret;
14454 }
14455
14456 static int
14457 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14458 {
14459   unformat_input_t *i = vam->input;
14460   vl_api_ipsec_spd_entry_add_del_t *mp;
14461   u8 is_add = 1, is_outbound = 0;
14462   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14463   i32 priority = 0;
14464   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14465   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14466   vl_api_address_t laddr_start = { }, laddr_stop =
14467   {
14468   }, raddr_start =
14469   {
14470   }, raddr_stop =
14471   {
14472   };
14473   int ret;
14474
14475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14476     {
14477       if (unformat (i, "del"))
14478         is_add = 0;
14479       if (unformat (i, "outbound"))
14480         is_outbound = 1;
14481       if (unformat (i, "inbound"))
14482         is_outbound = 0;
14483       else if (unformat (i, "spd_id %d", &spd_id))
14484         ;
14485       else if (unformat (i, "sa_id %d", &sa_id))
14486         ;
14487       else if (unformat (i, "priority %d", &priority))
14488         ;
14489       else if (unformat (i, "protocol %d", &protocol))
14490         ;
14491       else if (unformat (i, "lport_start %d", &lport_start))
14492         ;
14493       else if (unformat (i, "lport_stop %d", &lport_stop))
14494         ;
14495       else if (unformat (i, "rport_start %d", &rport_start))
14496         ;
14497       else if (unformat (i, "rport_stop %d", &rport_stop))
14498         ;
14499       else if (unformat (i, "laddr_start %U",
14500                          unformat_vl_api_address, &laddr_start))
14501         ;
14502       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14503                          &laddr_stop))
14504         ;
14505       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14506                          &raddr_start))
14507         ;
14508       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14509                          &raddr_stop))
14510         ;
14511       else
14512         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14513         {
14514           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14515             {
14516               clib_warning ("unsupported action: 'resolve'");
14517               return -99;
14518             }
14519         }
14520       else
14521         {
14522           clib_warning ("parse error '%U'", format_unformat_error, i);
14523           return -99;
14524         }
14525
14526     }
14527
14528   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14529
14530   mp->is_add = is_add;
14531
14532   mp->entry.spd_id = ntohl (spd_id);
14533   mp->entry.priority = ntohl (priority);
14534   mp->entry.is_outbound = is_outbound;
14535
14536   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14537                sizeof (vl_api_address_t));
14538   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14539                sizeof (vl_api_address_t));
14540   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14541                sizeof (vl_api_address_t));
14542   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14543                sizeof (vl_api_address_t));
14544
14545   mp->entry.protocol = (u8) protocol;
14546   mp->entry.local_port_start = ntohs ((u16) lport_start);
14547   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14548   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14549   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14550   mp->entry.policy = (u8) policy;
14551   mp->entry.sa_id = ntohl (sa_id);
14552
14553   S (mp);
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14560 {
14561   unformat_input_t *i = vam->input;
14562   vl_api_ipsec_sad_entry_add_del_t *mp;
14563   u32 sad_id = 0, spi = 0;
14564   u8 *ck = 0, *ik = 0;
14565   u8 is_add = 1;
14566
14567   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14568   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14569   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14570   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14571   vl_api_address_t tun_src, tun_dst;
14572   int ret;
14573
14574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14575     {
14576       if (unformat (i, "del"))
14577         is_add = 0;
14578       else if (unformat (i, "sad_id %d", &sad_id))
14579         ;
14580       else if (unformat (i, "spi %d", &spi))
14581         ;
14582       else if (unformat (i, "esp"))
14583         protocol = IPSEC_API_PROTO_ESP;
14584       else
14585         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14586         {
14587           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14588           if (ADDRESS_IP6 == tun_src.af)
14589             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14590         }
14591       else
14592         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14593         {
14594           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14595           if (ADDRESS_IP6 == tun_src.af)
14596             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14597         }
14598       else
14599         if (unformat (i, "crypto_alg %U",
14600                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14601         ;
14602       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14603         ;
14604       else if (unformat (i, "integ_alg %U",
14605                          unformat_ipsec_api_integ_alg, &integ_alg))
14606         ;
14607       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14608         ;
14609       else
14610         {
14611           clib_warning ("parse error '%U'", format_unformat_error, i);
14612           return -99;
14613         }
14614
14615     }
14616
14617   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14618
14619   mp->is_add = is_add;
14620   mp->entry.sad_id = ntohl (sad_id);
14621   mp->entry.protocol = protocol;
14622   mp->entry.spi = ntohl (spi);
14623   mp->entry.flags = flags;
14624
14625   mp->entry.crypto_algorithm = crypto_alg;
14626   mp->entry.integrity_algorithm = integ_alg;
14627   mp->entry.crypto_key.length = vec_len (ck);
14628   mp->entry.integrity_key.length = vec_len (ik);
14629
14630   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14631     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14632
14633   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14634     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14635
14636   if (ck)
14637     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14638   if (ik)
14639     clib_memcpy (mp->entry.integrity_key.data, ik,
14640                  mp->entry.integrity_key.length);
14641
14642   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14643     {
14644       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14645                    sizeof (mp->entry.tunnel_src));
14646       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14647                    sizeof (mp->entry.tunnel_dst));
14648     }
14649
14650   S (mp);
14651   W (ret);
14652   return ret;
14653 }
14654
14655 static int
14656 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14657 {
14658   unformat_input_t *i = vam->input;
14659   vl_api_ipsec_tunnel_if_add_del_t *mp;
14660   u32 local_spi = 0, remote_spi = 0;
14661   u32 crypto_alg = 0, integ_alg = 0;
14662   u8 *lck = NULL, *rck = NULL;
14663   u8 *lik = NULL, *rik = NULL;
14664   vl_api_address_t local_ip = { 0 };
14665   vl_api_address_t remote_ip = { 0 };
14666   f64 before = 0;
14667   u8 is_add = 1;
14668   u8 esn = 0;
14669   u8 anti_replay = 0;
14670   u8 renumber = 0;
14671   u32 instance = ~0;
14672   u32 count = 1, jj;
14673   int ret = -1;
14674
14675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14676     {
14677       if (unformat (i, "del"))
14678         is_add = 0;
14679       else if (unformat (i, "esn"))
14680         esn = 1;
14681       else if (unformat (i, "anti-replay"))
14682         anti_replay = 1;
14683       else if (unformat (i, "count %d", &count))
14684         ;
14685       else if (unformat (i, "local_spi %d", &local_spi))
14686         ;
14687       else if (unformat (i, "remote_spi %d", &remote_spi))
14688         ;
14689       else
14690         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14691         ;
14692       else
14693         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14694         ;
14695       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14696         ;
14697       else
14698         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14699         ;
14700       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14701         ;
14702       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14703         ;
14704       else
14705         if (unformat
14706             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14707         {
14708           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14709             {
14710               errmsg ("unsupported crypto-alg: '%U'\n",
14711                       format_ipsec_crypto_alg, crypto_alg);
14712               return -99;
14713             }
14714         }
14715       else
14716         if (unformat
14717             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14718         {
14719           if (integ_alg >= IPSEC_INTEG_N_ALG)
14720             {
14721               errmsg ("unsupported integ-alg: '%U'\n",
14722                       format_ipsec_integ_alg, integ_alg);
14723               return -99;
14724             }
14725         }
14726       else if (unformat (i, "instance %u", &instance))
14727         renumber = 1;
14728       else
14729         {
14730           errmsg ("parse error '%U'\n", format_unformat_error, i);
14731           return -99;
14732         }
14733     }
14734
14735   if (count > 1)
14736     {
14737       /* Turn on async mode */
14738       vam->async_mode = 1;
14739       vam->async_errors = 0;
14740       before = vat_time_now (vam);
14741     }
14742
14743   for (jj = 0; jj < count; jj++)
14744     {
14745       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14746
14747       mp->is_add = is_add;
14748       mp->esn = esn;
14749       mp->anti_replay = anti_replay;
14750
14751       if (jj > 0)
14752         increment_address (&remote_ip);
14753
14754       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14755       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14756
14757       mp->local_spi = htonl (local_spi + jj);
14758       mp->remote_spi = htonl (remote_spi + jj);
14759       mp->crypto_alg = (u8) crypto_alg;
14760
14761       mp->local_crypto_key_len = 0;
14762       if (lck)
14763         {
14764           mp->local_crypto_key_len = vec_len (lck);
14765           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14766             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14767           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14768         }
14769
14770       mp->remote_crypto_key_len = 0;
14771       if (rck)
14772         {
14773           mp->remote_crypto_key_len = vec_len (rck);
14774           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14775             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14776           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14777         }
14778
14779       mp->integ_alg = (u8) integ_alg;
14780
14781       mp->local_integ_key_len = 0;
14782       if (lik)
14783         {
14784           mp->local_integ_key_len = vec_len (lik);
14785           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14786             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14787           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14788         }
14789
14790       mp->remote_integ_key_len = 0;
14791       if (rik)
14792         {
14793           mp->remote_integ_key_len = vec_len (rik);
14794           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14795             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14796           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14797         }
14798
14799       if (renumber)
14800         {
14801           mp->renumber = renumber;
14802           mp->show_instance = ntohl (instance);
14803         }
14804       S (mp);
14805     }
14806
14807   /* When testing multiple add/del ops, use a control-ping to sync */
14808   if (count > 1)
14809     {
14810       vl_api_control_ping_t *mp_ping;
14811       f64 after;
14812       f64 timeout;
14813
14814       /* Shut off async mode */
14815       vam->async_mode = 0;
14816
14817       MPING (CONTROL_PING, mp_ping);
14818       S (mp_ping);
14819
14820       timeout = vat_time_now (vam) + 1.0;
14821       while (vat_time_now (vam) < timeout)
14822         if (vam->result_ready == 1)
14823           goto out;
14824       vam->retval = -99;
14825
14826     out:
14827       if (vam->retval == -99)
14828         errmsg ("timeout");
14829
14830       if (vam->async_errors > 0)
14831         {
14832           errmsg ("%d asynchronous errors", vam->async_errors);
14833           vam->retval = -98;
14834         }
14835       vam->async_errors = 0;
14836       after = vat_time_now (vam);
14837
14838       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14839       if (jj > 0)
14840         count = jj;
14841
14842       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14843              count, after - before, count / (after - before));
14844     }
14845   else
14846     {
14847       /* Wait for a reply... */
14848       W (ret);
14849       return ret;
14850     }
14851
14852   return ret;
14853 }
14854
14855 static void
14856 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14857 {
14858   vat_main_t *vam = &vat_main;
14859
14860   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14861          "crypto_key %U integ_alg %u integ_key %U flags %x "
14862          "tunnel_src_addr %U tunnel_dst_addr %U "
14863          "salt %u seq_outbound %lu last_seq_inbound %lu "
14864          "replay_window %lu\n",
14865          ntohl (mp->entry.sad_id),
14866          ntohl (mp->sw_if_index),
14867          ntohl (mp->entry.spi),
14868          ntohl (mp->entry.protocol),
14869          ntohl (mp->entry.crypto_algorithm),
14870          format_hex_bytes, mp->entry.crypto_key.data,
14871          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14872          format_hex_bytes, mp->entry.integrity_key.data,
14873          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14874          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14875          &mp->entry.tunnel_dst, ntohl (mp->salt),
14876          clib_net_to_host_u64 (mp->seq_outbound),
14877          clib_net_to_host_u64 (mp->last_seq_inbound),
14878          clib_net_to_host_u64 (mp->replay_window));
14879 }
14880
14881 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14882 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14883
14884 static void vl_api_ipsec_sa_details_t_handler_json
14885   (vl_api_ipsec_sa_details_t * mp)
14886 {
14887   vat_main_t *vam = &vat_main;
14888   vat_json_node_t *node = NULL;
14889   vl_api_ipsec_sad_flags_t flags;
14890
14891   if (VAT_JSON_ARRAY != vam->json_tree.type)
14892     {
14893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14894       vat_json_init_array (&vam->json_tree);
14895     }
14896   node = vat_json_array_add (&vam->json_tree);
14897
14898   vat_json_init_object (node);
14899   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14900   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14901   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14902   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14903   vat_json_object_add_uint (node, "crypto_alg",
14904                             ntohl (mp->entry.crypto_algorithm));
14905   vat_json_object_add_uint (node, "integ_alg",
14906                             ntohl (mp->entry.integrity_algorithm));
14907   flags = ntohl (mp->entry.flags);
14908   vat_json_object_add_uint (node, "use_esn",
14909                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14910   vat_json_object_add_uint (node, "use_anti_replay",
14911                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14912   vat_json_object_add_uint (node, "is_tunnel",
14913                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14914   vat_json_object_add_uint (node, "is_tunnel_ip6",
14915                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14916   vat_json_object_add_uint (node, "udp_encap",
14917                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14918   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14919                              mp->entry.crypto_key.length);
14920   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14921                              mp->entry.integrity_key.length);
14922   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14923   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14924   vat_json_object_add_uint (node, "replay_window",
14925                             clib_net_to_host_u64 (mp->replay_window));
14926 }
14927
14928 static int
14929 api_ipsec_sa_dump (vat_main_t * vam)
14930 {
14931   unformat_input_t *i = vam->input;
14932   vl_api_ipsec_sa_dump_t *mp;
14933   vl_api_control_ping_t *mp_ping;
14934   u32 sa_id = ~0;
14935   int ret;
14936
14937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (i, "sa_id %d", &sa_id))
14940         ;
14941       else
14942         {
14943           clib_warning ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947
14948   M (IPSEC_SA_DUMP, mp);
14949
14950   mp->sa_id = ntohl (sa_id);
14951
14952   S (mp);
14953
14954   /* Use a control ping for synchronization */
14955   M (CONTROL_PING, mp_ping);
14956   S (mp_ping);
14957
14958   W (ret);
14959   return ret;
14960 }
14961
14962 static int
14963 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14964 {
14965   unformat_input_t *i = vam->input;
14966   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14967   u32 sw_if_index = ~0;
14968   u32 sa_id = ~0;
14969   u8 is_outbound = (u8) ~ 0;
14970   int ret;
14971
14972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14973     {
14974       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14975         ;
14976       else if (unformat (i, "sa_id %d", &sa_id))
14977         ;
14978       else if (unformat (i, "outbound"))
14979         is_outbound = 1;
14980       else if (unformat (i, "inbound"))
14981         is_outbound = 0;
14982       else
14983         {
14984           clib_warning ("parse error '%U'", format_unformat_error, i);
14985           return -99;
14986         }
14987     }
14988
14989   if (sw_if_index == ~0)
14990     {
14991       errmsg ("interface must be specified");
14992       return -99;
14993     }
14994
14995   if (sa_id == ~0)
14996     {
14997       errmsg ("SA ID must be specified");
14998       return -99;
14999     }
15000
15001   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15002
15003   mp->sw_if_index = htonl (sw_if_index);
15004   mp->sa_id = htonl (sa_id);
15005   mp->is_outbound = is_outbound;
15006
15007   S (mp);
15008   W (ret);
15009
15010   return ret;
15011 }
15012
15013 static int
15014 api_get_first_msg_id (vat_main_t * vam)
15015 {
15016   vl_api_get_first_msg_id_t *mp;
15017   unformat_input_t *i = vam->input;
15018   u8 *name;
15019   u8 name_set = 0;
15020   int ret;
15021
15022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15023     {
15024       if (unformat (i, "client %s", &name))
15025         name_set = 1;
15026       else
15027         break;
15028     }
15029
15030   if (name_set == 0)
15031     {
15032       errmsg ("missing client name");
15033       return -99;
15034     }
15035   vec_add1 (name, 0);
15036
15037   if (vec_len (name) > 63)
15038     {
15039       errmsg ("client name too long");
15040       return -99;
15041     }
15042
15043   M (GET_FIRST_MSG_ID, mp);
15044   clib_memcpy (mp->name, name, vec_len (name));
15045   S (mp);
15046   W (ret);
15047   return ret;
15048 }
15049
15050 static int
15051 api_cop_interface_enable_disable (vat_main_t * vam)
15052 {
15053   unformat_input_t *line_input = vam->input;
15054   vl_api_cop_interface_enable_disable_t *mp;
15055   u32 sw_if_index = ~0;
15056   u8 enable_disable = 1;
15057   int ret;
15058
15059   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15060     {
15061       if (unformat (line_input, "disable"))
15062         enable_disable = 0;
15063       if (unformat (line_input, "enable"))
15064         enable_disable = 1;
15065       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15066                          vam, &sw_if_index))
15067         ;
15068       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15069         ;
15070       else
15071         break;
15072     }
15073
15074   if (sw_if_index == ~0)
15075     {
15076       errmsg ("missing interface name or sw_if_index");
15077       return -99;
15078     }
15079
15080   /* Construct the API message */
15081   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15082   mp->sw_if_index = ntohl (sw_if_index);
15083   mp->enable_disable = enable_disable;
15084
15085   /* send it... */
15086   S (mp);
15087   /* Wait for the reply */
15088   W (ret);
15089   return ret;
15090 }
15091
15092 static int
15093 api_cop_whitelist_enable_disable (vat_main_t * vam)
15094 {
15095   unformat_input_t *line_input = vam->input;
15096   vl_api_cop_whitelist_enable_disable_t *mp;
15097   u32 sw_if_index = ~0;
15098   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15099   u32 fib_id = 0;
15100   int ret;
15101
15102   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15103     {
15104       if (unformat (line_input, "ip4"))
15105         ip4 = 1;
15106       else if (unformat (line_input, "ip6"))
15107         ip6 = 1;
15108       else if (unformat (line_input, "default"))
15109         default_cop = 1;
15110       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15111                          vam, &sw_if_index))
15112         ;
15113       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15114         ;
15115       else if (unformat (line_input, "fib-id %d", &fib_id))
15116         ;
15117       else
15118         break;
15119     }
15120
15121   if (sw_if_index == ~0)
15122     {
15123       errmsg ("missing interface name or sw_if_index");
15124       return -99;
15125     }
15126
15127   /* Construct the API message */
15128   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15129   mp->sw_if_index = ntohl (sw_if_index);
15130   mp->fib_id = ntohl (fib_id);
15131   mp->ip4 = ip4;
15132   mp->ip6 = ip6;
15133   mp->default_cop = default_cop;
15134
15135   /* send it... */
15136   S (mp);
15137   /* Wait for the reply */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 static int
15143 api_get_node_graph (vat_main_t * vam)
15144 {
15145   vl_api_get_node_graph_t *mp;
15146   int ret;
15147
15148   M (GET_NODE_GRAPH, mp);
15149
15150   /* send it... */
15151   S (mp);
15152   /* Wait for the reply */
15153   W (ret);
15154   return ret;
15155 }
15156
15157 /* *INDENT-OFF* */
15158 /** Used for parsing LISP eids */
15159 typedef CLIB_PACKED(struct{
15160   u8 addr[16];   /**< eid address */
15161   u32 len;       /**< prefix length if IP */
15162   u8 type;      /**< type of eid */
15163 }) lisp_eid_vat_t;
15164 /* *INDENT-ON* */
15165
15166 static uword
15167 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15168 {
15169   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15170
15171   clib_memset (a, 0, sizeof (a[0]));
15172
15173   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15174     {
15175       a->type = 0;              /* ipv4 type */
15176     }
15177   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15178     {
15179       a->type = 1;              /* ipv6 type */
15180     }
15181   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15182     {
15183       a->type = 2;              /* mac type */
15184     }
15185   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15186     {
15187       a->type = 3;              /* NSH type */
15188       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15189       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15190     }
15191   else
15192     {
15193       return 0;
15194     }
15195
15196   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15197     {
15198       return 0;
15199     }
15200
15201   return 1;
15202 }
15203
15204 static int
15205 lisp_eid_size_vat (u8 type)
15206 {
15207   switch (type)
15208     {
15209     case 0:
15210       return 4;
15211     case 1:
15212       return 16;
15213     case 2:
15214       return 6;
15215     case 3:
15216       return 5;
15217     }
15218   return 0;
15219 }
15220
15221 static void
15222 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15223 {
15224   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15225 }
15226
15227 static int
15228 api_one_add_del_locator_set (vat_main_t * vam)
15229 {
15230   unformat_input_t *input = vam->input;
15231   vl_api_one_add_del_locator_set_t *mp;
15232   u8 is_add = 1;
15233   u8 *locator_set_name = NULL;
15234   u8 locator_set_name_set = 0;
15235   vl_api_local_locator_t locator, *locators = 0;
15236   u32 sw_if_index, priority, weight;
15237   u32 data_len = 0;
15238
15239   int ret;
15240   /* Parse args required to build the message */
15241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15242     {
15243       if (unformat (input, "del"))
15244         {
15245           is_add = 0;
15246         }
15247       else if (unformat (input, "locator-set %s", &locator_set_name))
15248         {
15249           locator_set_name_set = 1;
15250         }
15251       else if (unformat (input, "sw_if_index %u p %u w %u",
15252                          &sw_if_index, &priority, &weight))
15253         {
15254           locator.sw_if_index = htonl (sw_if_index);
15255           locator.priority = priority;
15256           locator.weight = weight;
15257           vec_add1 (locators, locator);
15258         }
15259       else
15260         if (unformat
15261             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15262              &sw_if_index, &priority, &weight))
15263         {
15264           locator.sw_if_index = htonl (sw_if_index);
15265           locator.priority = priority;
15266           locator.weight = weight;
15267           vec_add1 (locators, locator);
15268         }
15269       else
15270         break;
15271     }
15272
15273   if (locator_set_name_set == 0)
15274     {
15275       errmsg ("missing locator-set name");
15276       vec_free (locators);
15277       return -99;
15278     }
15279
15280   if (vec_len (locator_set_name) > 64)
15281     {
15282       errmsg ("locator-set name too long");
15283       vec_free (locator_set_name);
15284       vec_free (locators);
15285       return -99;
15286     }
15287   vec_add1 (locator_set_name, 0);
15288
15289   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15290
15291   /* Construct the API message */
15292   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15293
15294   mp->is_add = is_add;
15295   clib_memcpy (mp->locator_set_name, locator_set_name,
15296                vec_len (locator_set_name));
15297   vec_free (locator_set_name);
15298
15299   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15300   if (locators)
15301     clib_memcpy (mp->locators, locators, data_len);
15302   vec_free (locators);
15303
15304   /* send it... */
15305   S (mp);
15306
15307   /* Wait for a reply... */
15308   W (ret);
15309   return ret;
15310 }
15311
15312 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15313
15314 static int
15315 api_one_add_del_locator (vat_main_t * vam)
15316 {
15317   unformat_input_t *input = vam->input;
15318   vl_api_one_add_del_locator_t *mp;
15319   u32 tmp_if_index = ~0;
15320   u32 sw_if_index = ~0;
15321   u8 sw_if_index_set = 0;
15322   u8 sw_if_index_if_name_set = 0;
15323   u32 priority = ~0;
15324   u8 priority_set = 0;
15325   u32 weight = ~0;
15326   u8 weight_set = 0;
15327   u8 is_add = 1;
15328   u8 *locator_set_name = NULL;
15329   u8 locator_set_name_set = 0;
15330   int ret;
15331
15332   /* Parse args required to build the message */
15333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15334     {
15335       if (unformat (input, "del"))
15336         {
15337           is_add = 0;
15338         }
15339       else if (unformat (input, "locator-set %s", &locator_set_name))
15340         {
15341           locator_set_name_set = 1;
15342         }
15343       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15344                          &tmp_if_index))
15345         {
15346           sw_if_index_if_name_set = 1;
15347           sw_if_index = tmp_if_index;
15348         }
15349       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15350         {
15351           sw_if_index_set = 1;
15352           sw_if_index = tmp_if_index;
15353         }
15354       else if (unformat (input, "p %d", &priority))
15355         {
15356           priority_set = 1;
15357         }
15358       else if (unformat (input, "w %d", &weight))
15359         {
15360           weight_set = 1;
15361         }
15362       else
15363         break;
15364     }
15365
15366   if (locator_set_name_set == 0)
15367     {
15368       errmsg ("missing locator-set name");
15369       return -99;
15370     }
15371
15372   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15373     {
15374       errmsg ("missing sw_if_index");
15375       vec_free (locator_set_name);
15376       return -99;
15377     }
15378
15379   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15380     {
15381       errmsg ("cannot use both params interface name and sw_if_index");
15382       vec_free (locator_set_name);
15383       return -99;
15384     }
15385
15386   if (priority_set == 0)
15387     {
15388       errmsg ("missing locator-set priority");
15389       vec_free (locator_set_name);
15390       return -99;
15391     }
15392
15393   if (weight_set == 0)
15394     {
15395       errmsg ("missing locator-set weight");
15396       vec_free (locator_set_name);
15397       return -99;
15398     }
15399
15400   if (vec_len (locator_set_name) > 64)
15401     {
15402       errmsg ("locator-set name too long");
15403       vec_free (locator_set_name);
15404       return -99;
15405     }
15406   vec_add1 (locator_set_name, 0);
15407
15408   /* Construct the API message */
15409   M (ONE_ADD_DEL_LOCATOR, mp);
15410
15411   mp->is_add = is_add;
15412   mp->sw_if_index = ntohl (sw_if_index);
15413   mp->priority = priority;
15414   mp->weight = weight;
15415   clib_memcpy (mp->locator_set_name, locator_set_name,
15416                vec_len (locator_set_name));
15417   vec_free (locator_set_name);
15418
15419   /* send it... */
15420   S (mp);
15421
15422   /* Wait for a reply... */
15423   W (ret);
15424   return ret;
15425 }
15426
15427 #define api_lisp_add_del_locator api_one_add_del_locator
15428
15429 uword
15430 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15431 {
15432   u32 *key_id = va_arg (*args, u32 *);
15433   u8 *s = 0;
15434
15435   if (unformat (input, "%s", &s))
15436     {
15437       if (!strcmp ((char *) s, "sha1"))
15438         key_id[0] = HMAC_SHA_1_96;
15439       else if (!strcmp ((char *) s, "sha256"))
15440         key_id[0] = HMAC_SHA_256_128;
15441       else
15442         {
15443           clib_warning ("invalid key_id: '%s'", s);
15444           key_id[0] = HMAC_NO_KEY;
15445         }
15446     }
15447   else
15448     return 0;
15449
15450   vec_free (s);
15451   return 1;
15452 }
15453
15454 static int
15455 api_one_add_del_local_eid (vat_main_t * vam)
15456 {
15457   unformat_input_t *input = vam->input;
15458   vl_api_one_add_del_local_eid_t *mp;
15459   u8 is_add = 1;
15460   u8 eid_set = 0;
15461   lisp_eid_vat_t _eid, *eid = &_eid;
15462   u8 *locator_set_name = 0;
15463   u8 locator_set_name_set = 0;
15464   u32 vni = 0;
15465   u16 key_id = 0;
15466   u8 *key = 0;
15467   int ret;
15468
15469   /* Parse args required to build the message */
15470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (input, "del"))
15473         {
15474           is_add = 0;
15475         }
15476       else if (unformat (input, "vni %d", &vni))
15477         {
15478           ;
15479         }
15480       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15481         {
15482           eid_set = 1;
15483         }
15484       else if (unformat (input, "locator-set %s", &locator_set_name))
15485         {
15486           locator_set_name_set = 1;
15487         }
15488       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15489         ;
15490       else if (unformat (input, "secret-key %_%v%_", &key))
15491         ;
15492       else
15493         break;
15494     }
15495
15496   if (locator_set_name_set == 0)
15497     {
15498       errmsg ("missing locator-set name");
15499       return -99;
15500     }
15501
15502   if (0 == eid_set)
15503     {
15504       errmsg ("EID address not set!");
15505       vec_free (locator_set_name);
15506       return -99;
15507     }
15508
15509   if (key && (0 == key_id))
15510     {
15511       errmsg ("invalid key_id!");
15512       return -99;
15513     }
15514
15515   if (vec_len (key) > 64)
15516     {
15517       errmsg ("key too long");
15518       vec_free (key);
15519       return -99;
15520     }
15521
15522   if (vec_len (locator_set_name) > 64)
15523     {
15524       errmsg ("locator-set name too long");
15525       vec_free (locator_set_name);
15526       return -99;
15527     }
15528   vec_add1 (locator_set_name, 0);
15529
15530   /* Construct the API message */
15531   M (ONE_ADD_DEL_LOCAL_EID, mp);
15532
15533   mp->is_add = is_add;
15534   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15535   mp->eid_type = eid->type;
15536   mp->prefix_len = eid->len;
15537   mp->vni = clib_host_to_net_u32 (vni);
15538   mp->key_id = clib_host_to_net_u16 (key_id);
15539   clib_memcpy (mp->locator_set_name, locator_set_name,
15540                vec_len (locator_set_name));
15541   clib_memcpy (mp->key, key, vec_len (key));
15542
15543   vec_free (locator_set_name);
15544   vec_free (key);
15545
15546   /* send it... */
15547   S (mp);
15548
15549   /* Wait for a reply... */
15550   W (ret);
15551   return ret;
15552 }
15553
15554 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15555
15556 static int
15557 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15558 {
15559   u32 dp_table = 0, vni = 0;;
15560   unformat_input_t *input = vam->input;
15561   vl_api_gpe_add_del_fwd_entry_t *mp;
15562   u8 is_add = 1;
15563   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15564   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15565   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15566   u32 action = ~0, w;
15567   ip4_address_t rmt_rloc4, lcl_rloc4;
15568   ip6_address_t rmt_rloc6, lcl_rloc6;
15569   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15570   int ret;
15571
15572   clib_memset (&rloc, 0, sizeof (rloc));
15573
15574   /* Parse args required to build the message */
15575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15576     {
15577       if (unformat (input, "del"))
15578         is_add = 0;
15579       else if (unformat (input, "add"))
15580         is_add = 1;
15581       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15582         {
15583           rmt_eid_set = 1;
15584         }
15585       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15586         {
15587           lcl_eid_set = 1;
15588         }
15589       else if (unformat (input, "vrf %d", &dp_table))
15590         ;
15591       else if (unformat (input, "bd %d", &dp_table))
15592         ;
15593       else if (unformat (input, "vni %d", &vni))
15594         ;
15595       else if (unformat (input, "w %d", &w))
15596         {
15597           if (!curr_rloc)
15598             {
15599               errmsg ("No RLOC configured for setting priority/weight!");
15600               return -99;
15601             }
15602           curr_rloc->weight = w;
15603         }
15604       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15605                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15606         {
15607           rloc.is_ip4 = 1;
15608
15609           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15610           rloc.weight = 0;
15611           vec_add1 (lcl_locs, rloc);
15612
15613           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15614           vec_add1 (rmt_locs, rloc);
15615           /* weight saved in rmt loc */
15616           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15617         }
15618       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15619                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15620         {
15621           rloc.is_ip4 = 0;
15622           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15623           rloc.weight = 0;
15624           vec_add1 (lcl_locs, rloc);
15625
15626           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15627           vec_add1 (rmt_locs, rloc);
15628           /* weight saved in rmt loc */
15629           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15630         }
15631       else if (unformat (input, "action %d", &action))
15632         {
15633           ;
15634         }
15635       else
15636         {
15637           clib_warning ("parse error '%U'", format_unformat_error, input);
15638           return -99;
15639         }
15640     }
15641
15642   if (!rmt_eid_set)
15643     {
15644       errmsg ("remote eid addresses not set");
15645       return -99;
15646     }
15647
15648   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15649     {
15650       errmsg ("eid types don't match");
15651       return -99;
15652     }
15653
15654   if (0 == rmt_locs && (u32) ~ 0 == action)
15655     {
15656       errmsg ("action not set for negative mapping");
15657       return -99;
15658     }
15659
15660   /* Construct the API message */
15661   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15662       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15663
15664   mp->is_add = is_add;
15665   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15666   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15667   mp->eid_type = rmt_eid->type;
15668   mp->dp_table = clib_host_to_net_u32 (dp_table);
15669   mp->vni = clib_host_to_net_u32 (vni);
15670   mp->rmt_len = rmt_eid->len;
15671   mp->lcl_len = lcl_eid->len;
15672   mp->action = action;
15673
15674   if (0 != rmt_locs && 0 != lcl_locs)
15675     {
15676       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15677       clib_memcpy (mp->locs, lcl_locs,
15678                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15679
15680       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15681       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15682                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15683     }
15684   vec_free (lcl_locs);
15685   vec_free (rmt_locs);
15686
15687   /* send it... */
15688   S (mp);
15689
15690   /* Wait for a reply... */
15691   W (ret);
15692   return ret;
15693 }
15694
15695 static int
15696 api_one_add_del_map_server (vat_main_t * vam)
15697 {
15698   unformat_input_t *input = vam->input;
15699   vl_api_one_add_del_map_server_t *mp;
15700   u8 is_add = 1;
15701   u8 ipv4_set = 0;
15702   u8 ipv6_set = 0;
15703   ip4_address_t ipv4;
15704   ip6_address_t ipv6;
15705   int ret;
15706
15707   /* Parse args required to build the message */
15708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15709     {
15710       if (unformat (input, "del"))
15711         {
15712           is_add = 0;
15713         }
15714       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15715         {
15716           ipv4_set = 1;
15717         }
15718       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15719         {
15720           ipv6_set = 1;
15721         }
15722       else
15723         break;
15724     }
15725
15726   if (ipv4_set && ipv6_set)
15727     {
15728       errmsg ("both eid v4 and v6 addresses set");
15729       return -99;
15730     }
15731
15732   if (!ipv4_set && !ipv6_set)
15733     {
15734       errmsg ("eid addresses not set");
15735       return -99;
15736     }
15737
15738   /* Construct the API message */
15739   M (ONE_ADD_DEL_MAP_SERVER, mp);
15740
15741   mp->is_add = is_add;
15742   if (ipv6_set)
15743     {
15744       mp->is_ipv6 = 1;
15745       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15746     }
15747   else
15748     {
15749       mp->is_ipv6 = 0;
15750       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15751     }
15752
15753   /* send it... */
15754   S (mp);
15755
15756   /* Wait for a reply... */
15757   W (ret);
15758   return ret;
15759 }
15760
15761 #define api_lisp_add_del_map_server api_one_add_del_map_server
15762
15763 static int
15764 api_one_add_del_map_resolver (vat_main_t * vam)
15765 {
15766   unformat_input_t *input = vam->input;
15767   vl_api_one_add_del_map_resolver_t *mp;
15768   u8 is_add = 1;
15769   u8 ipv4_set = 0;
15770   u8 ipv6_set = 0;
15771   ip4_address_t ipv4;
15772   ip6_address_t ipv6;
15773   int ret;
15774
15775   /* Parse args required to build the message */
15776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat (input, "del"))
15779         {
15780           is_add = 0;
15781         }
15782       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15783         {
15784           ipv4_set = 1;
15785         }
15786       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15787         {
15788           ipv6_set = 1;
15789         }
15790       else
15791         break;
15792     }
15793
15794   if (ipv4_set && ipv6_set)
15795     {
15796       errmsg ("both eid v4 and v6 addresses set");
15797       return -99;
15798     }
15799
15800   if (!ipv4_set && !ipv6_set)
15801     {
15802       errmsg ("eid addresses not set");
15803       return -99;
15804     }
15805
15806   /* Construct the API message */
15807   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15808
15809   mp->is_add = is_add;
15810   if (ipv6_set)
15811     {
15812       mp->is_ipv6 = 1;
15813       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15814     }
15815   else
15816     {
15817       mp->is_ipv6 = 0;
15818       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15819     }
15820
15821   /* send it... */
15822   S (mp);
15823
15824   /* Wait for a reply... */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15830
15831 static int
15832 api_lisp_gpe_enable_disable (vat_main_t * vam)
15833 {
15834   unformat_input_t *input = vam->input;
15835   vl_api_gpe_enable_disable_t *mp;
15836   u8 is_set = 0;
15837   u8 is_en = 1;
15838   int ret;
15839
15840   /* Parse args required to build the message */
15841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15842     {
15843       if (unformat (input, "enable"))
15844         {
15845           is_set = 1;
15846           is_en = 1;
15847         }
15848       else if (unformat (input, "disable"))
15849         {
15850           is_set = 1;
15851           is_en = 0;
15852         }
15853       else
15854         break;
15855     }
15856
15857   if (is_set == 0)
15858     {
15859       errmsg ("Value not set");
15860       return -99;
15861     }
15862
15863   /* Construct the API message */
15864   M (GPE_ENABLE_DISABLE, mp);
15865
15866   mp->is_en = is_en;
15867
15868   /* send it... */
15869   S (mp);
15870
15871   /* Wait for a reply... */
15872   W (ret);
15873   return ret;
15874 }
15875
15876 static int
15877 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15878 {
15879   unformat_input_t *input = vam->input;
15880   vl_api_one_rloc_probe_enable_disable_t *mp;
15881   u8 is_set = 0;
15882   u8 is_en = 0;
15883   int ret;
15884
15885   /* Parse args required to build the message */
15886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15887     {
15888       if (unformat (input, "enable"))
15889         {
15890           is_set = 1;
15891           is_en = 1;
15892         }
15893       else if (unformat (input, "disable"))
15894         is_set = 1;
15895       else
15896         break;
15897     }
15898
15899   if (!is_set)
15900     {
15901       errmsg ("Value not set");
15902       return -99;
15903     }
15904
15905   /* Construct the API message */
15906   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15907
15908   mp->is_enabled = is_en;
15909
15910   /* send it... */
15911   S (mp);
15912
15913   /* Wait for a reply... */
15914   W (ret);
15915   return ret;
15916 }
15917
15918 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15919
15920 static int
15921 api_one_map_register_enable_disable (vat_main_t * vam)
15922 {
15923   unformat_input_t *input = vam->input;
15924   vl_api_one_map_register_enable_disable_t *mp;
15925   u8 is_set = 0;
15926   u8 is_en = 0;
15927   int ret;
15928
15929   /* Parse args required to build the message */
15930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15931     {
15932       if (unformat (input, "enable"))
15933         {
15934           is_set = 1;
15935           is_en = 1;
15936         }
15937       else if (unformat (input, "disable"))
15938         is_set = 1;
15939       else
15940         break;
15941     }
15942
15943   if (!is_set)
15944     {
15945       errmsg ("Value not set");
15946       return -99;
15947     }
15948
15949   /* Construct the API message */
15950   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15951
15952   mp->is_enabled = is_en;
15953
15954   /* send it... */
15955   S (mp);
15956
15957   /* Wait for a reply... */
15958   W (ret);
15959   return ret;
15960 }
15961
15962 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15963
15964 static int
15965 api_one_enable_disable (vat_main_t * vam)
15966 {
15967   unformat_input_t *input = vam->input;
15968   vl_api_one_enable_disable_t *mp;
15969   u8 is_set = 0;
15970   u8 is_en = 0;
15971   int ret;
15972
15973   /* Parse args required to build the message */
15974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15975     {
15976       if (unformat (input, "enable"))
15977         {
15978           is_set = 1;
15979           is_en = 1;
15980         }
15981       else if (unformat (input, "disable"))
15982         {
15983           is_set = 1;
15984         }
15985       else
15986         break;
15987     }
15988
15989   if (!is_set)
15990     {
15991       errmsg ("Value not set");
15992       return -99;
15993     }
15994
15995   /* Construct the API message */
15996   M (ONE_ENABLE_DISABLE, mp);
15997
15998   mp->is_en = is_en;
15999
16000   /* send it... */
16001   S (mp);
16002
16003   /* Wait for a reply... */
16004   W (ret);
16005   return ret;
16006 }
16007
16008 #define api_lisp_enable_disable api_one_enable_disable
16009
16010 static int
16011 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16012 {
16013   unformat_input_t *input = vam->input;
16014   vl_api_one_enable_disable_xtr_mode_t *mp;
16015   u8 is_set = 0;
16016   u8 is_en = 0;
16017   int ret;
16018
16019   /* Parse args required to build the message */
16020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16021     {
16022       if (unformat (input, "enable"))
16023         {
16024           is_set = 1;
16025           is_en = 1;
16026         }
16027       else if (unformat (input, "disable"))
16028         {
16029           is_set = 1;
16030         }
16031       else
16032         break;
16033     }
16034
16035   if (!is_set)
16036     {
16037       errmsg ("Value not set");
16038       return -99;
16039     }
16040
16041   /* Construct the API message */
16042   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16043
16044   mp->is_en = is_en;
16045
16046   /* send it... */
16047   S (mp);
16048
16049   /* Wait for a reply... */
16050   W (ret);
16051   return ret;
16052 }
16053
16054 static int
16055 api_one_show_xtr_mode (vat_main_t * vam)
16056 {
16057   vl_api_one_show_xtr_mode_t *mp;
16058   int ret;
16059
16060   /* Construct the API message */
16061   M (ONE_SHOW_XTR_MODE, mp);
16062
16063   /* send it... */
16064   S (mp);
16065
16066   /* Wait for a reply... */
16067   W (ret);
16068   return ret;
16069 }
16070
16071 static int
16072 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16073 {
16074   unformat_input_t *input = vam->input;
16075   vl_api_one_enable_disable_pitr_mode_t *mp;
16076   u8 is_set = 0;
16077   u8 is_en = 0;
16078   int ret;
16079
16080   /* Parse args required to build the message */
16081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16082     {
16083       if (unformat (input, "enable"))
16084         {
16085           is_set = 1;
16086           is_en = 1;
16087         }
16088       else if (unformat (input, "disable"))
16089         {
16090           is_set = 1;
16091         }
16092       else
16093         break;
16094     }
16095
16096   if (!is_set)
16097     {
16098       errmsg ("Value not set");
16099       return -99;
16100     }
16101
16102   /* Construct the API message */
16103   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16104
16105   mp->is_en = is_en;
16106
16107   /* send it... */
16108   S (mp);
16109
16110   /* Wait for a reply... */
16111   W (ret);
16112   return ret;
16113 }
16114
16115 static int
16116 api_one_show_pitr_mode (vat_main_t * vam)
16117 {
16118   vl_api_one_show_pitr_mode_t *mp;
16119   int ret;
16120
16121   /* Construct the API message */
16122   M (ONE_SHOW_PITR_MODE, mp);
16123
16124   /* send it... */
16125   S (mp);
16126
16127   /* Wait for a reply... */
16128   W (ret);
16129   return ret;
16130 }
16131
16132 static int
16133 api_one_enable_disable_petr_mode (vat_main_t * vam)
16134 {
16135   unformat_input_t *input = vam->input;
16136   vl_api_one_enable_disable_petr_mode_t *mp;
16137   u8 is_set = 0;
16138   u8 is_en = 0;
16139   int ret;
16140
16141   /* Parse args required to build the message */
16142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16143     {
16144       if (unformat (input, "enable"))
16145         {
16146           is_set = 1;
16147           is_en = 1;
16148         }
16149       else if (unformat (input, "disable"))
16150         {
16151           is_set = 1;
16152         }
16153       else
16154         break;
16155     }
16156
16157   if (!is_set)
16158     {
16159       errmsg ("Value not set");
16160       return -99;
16161     }
16162
16163   /* Construct the API message */
16164   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16165
16166   mp->is_en = is_en;
16167
16168   /* send it... */
16169   S (mp);
16170
16171   /* Wait for a reply... */
16172   W (ret);
16173   return ret;
16174 }
16175
16176 static int
16177 api_one_show_petr_mode (vat_main_t * vam)
16178 {
16179   vl_api_one_show_petr_mode_t *mp;
16180   int ret;
16181
16182   /* Construct the API message */
16183   M (ONE_SHOW_PETR_MODE, mp);
16184
16185   /* send it... */
16186   S (mp);
16187
16188   /* Wait for a reply... */
16189   W (ret);
16190   return ret;
16191 }
16192
16193 static int
16194 api_show_one_map_register_state (vat_main_t * vam)
16195 {
16196   vl_api_show_one_map_register_state_t *mp;
16197   int ret;
16198
16199   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16200
16201   /* send */
16202   S (mp);
16203
16204   /* wait for reply */
16205   W (ret);
16206   return ret;
16207 }
16208
16209 #define api_show_lisp_map_register_state api_show_one_map_register_state
16210
16211 static int
16212 api_show_one_rloc_probe_state (vat_main_t * vam)
16213 {
16214   vl_api_show_one_rloc_probe_state_t *mp;
16215   int ret;
16216
16217   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16218
16219   /* send */
16220   S (mp);
16221
16222   /* wait for reply */
16223   W (ret);
16224   return ret;
16225 }
16226
16227 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16228
16229 static int
16230 api_one_add_del_ndp_entry (vat_main_t * vam)
16231 {
16232   vl_api_one_add_del_ndp_entry_t *mp;
16233   unformat_input_t *input = vam->input;
16234   u8 is_add = 1;
16235   u8 mac_set = 0;
16236   u8 bd_set = 0;
16237   u8 ip_set = 0;
16238   u8 mac[6] = { 0, };
16239   u8 ip6[16] = { 0, };
16240   u32 bd = ~0;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "del"))
16247         is_add = 0;
16248       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16249         mac_set = 1;
16250       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16251         ip_set = 1;
16252       else if (unformat (input, "bd %d", &bd))
16253         bd_set = 1;
16254       else
16255         {
16256           errmsg ("parse error '%U'", format_unformat_error, input);
16257           return -99;
16258         }
16259     }
16260
16261   if (!bd_set || !ip_set || (!mac_set && is_add))
16262     {
16263       errmsg ("Missing BD, IP or MAC!");
16264       return -99;
16265     }
16266
16267   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16268   mp->is_add = is_add;
16269   clib_memcpy (mp->mac, mac, 6);
16270   mp->bd = clib_host_to_net_u32 (bd);
16271   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16272
16273   /* send */
16274   S (mp);
16275
16276   /* wait for reply */
16277   W (ret);
16278   return ret;
16279 }
16280
16281 static int
16282 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16283 {
16284   vl_api_one_add_del_l2_arp_entry_t *mp;
16285   unformat_input_t *input = vam->input;
16286   u8 is_add = 1;
16287   u8 mac_set = 0;
16288   u8 bd_set = 0;
16289   u8 ip_set = 0;
16290   u8 mac[6] = { 0, };
16291   u32 ip4 = 0, bd = ~0;
16292   int ret;
16293
16294   /* Parse args required to build the message */
16295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16296     {
16297       if (unformat (input, "del"))
16298         is_add = 0;
16299       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16300         mac_set = 1;
16301       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16302         ip_set = 1;
16303       else if (unformat (input, "bd %d", &bd))
16304         bd_set = 1;
16305       else
16306         {
16307           errmsg ("parse error '%U'", format_unformat_error, input);
16308           return -99;
16309         }
16310     }
16311
16312   if (!bd_set || !ip_set || (!mac_set && is_add))
16313     {
16314       errmsg ("Missing BD, IP or MAC!");
16315       return -99;
16316     }
16317
16318   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16319   mp->is_add = is_add;
16320   clib_memcpy (mp->mac, mac, 6);
16321   mp->bd = clib_host_to_net_u32 (bd);
16322   mp->ip4 = ip4;
16323
16324   /* send */
16325   S (mp);
16326
16327   /* wait for reply */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 static int
16333 api_one_ndp_bd_get (vat_main_t * vam)
16334 {
16335   vl_api_one_ndp_bd_get_t *mp;
16336   int ret;
16337
16338   M (ONE_NDP_BD_GET, mp);
16339
16340   /* send */
16341   S (mp);
16342
16343   /* wait for reply */
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_one_ndp_entries_get (vat_main_t * vam)
16350 {
16351   vl_api_one_ndp_entries_get_t *mp;
16352   unformat_input_t *input = vam->input;
16353   u8 bd_set = 0;
16354   u32 bd = ~0;
16355   int ret;
16356
16357   /* Parse args required to build the message */
16358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16359     {
16360       if (unformat (input, "bd %d", &bd))
16361         bd_set = 1;
16362       else
16363         {
16364           errmsg ("parse error '%U'", format_unformat_error, input);
16365           return -99;
16366         }
16367     }
16368
16369   if (!bd_set)
16370     {
16371       errmsg ("Expected bridge domain!");
16372       return -99;
16373     }
16374
16375   M (ONE_NDP_ENTRIES_GET, mp);
16376   mp->bd = clib_host_to_net_u32 (bd);
16377
16378   /* send */
16379   S (mp);
16380
16381   /* wait for reply */
16382   W (ret);
16383   return ret;
16384 }
16385
16386 static int
16387 api_one_l2_arp_bd_get (vat_main_t * vam)
16388 {
16389   vl_api_one_l2_arp_bd_get_t *mp;
16390   int ret;
16391
16392   M (ONE_L2_ARP_BD_GET, mp);
16393
16394   /* send */
16395   S (mp);
16396
16397   /* wait for reply */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_one_l2_arp_entries_get (vat_main_t * vam)
16404 {
16405   vl_api_one_l2_arp_entries_get_t *mp;
16406   unformat_input_t *input = vam->input;
16407   u8 bd_set = 0;
16408   u32 bd = ~0;
16409   int ret;
16410
16411   /* Parse args required to build the message */
16412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16413     {
16414       if (unformat (input, "bd %d", &bd))
16415         bd_set = 1;
16416       else
16417         {
16418           errmsg ("parse error '%U'", format_unformat_error, input);
16419           return -99;
16420         }
16421     }
16422
16423   if (!bd_set)
16424     {
16425       errmsg ("Expected bridge domain!");
16426       return -99;
16427     }
16428
16429   M (ONE_L2_ARP_ENTRIES_GET, mp);
16430   mp->bd = clib_host_to_net_u32 (bd);
16431
16432   /* send */
16433   S (mp);
16434
16435   /* wait for reply */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 static int
16441 api_one_stats_enable_disable (vat_main_t * vam)
16442 {
16443   vl_api_one_stats_enable_disable_t *mp;
16444   unformat_input_t *input = vam->input;
16445   u8 is_set = 0;
16446   u8 is_en = 0;
16447   int ret;
16448
16449   /* Parse args required to build the message */
16450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (input, "enable"))
16453         {
16454           is_set = 1;
16455           is_en = 1;
16456         }
16457       else if (unformat (input, "disable"))
16458         {
16459           is_set = 1;
16460         }
16461       else
16462         break;
16463     }
16464
16465   if (!is_set)
16466     {
16467       errmsg ("Value not set");
16468       return -99;
16469     }
16470
16471   M (ONE_STATS_ENABLE_DISABLE, mp);
16472   mp->is_en = is_en;
16473
16474   /* send */
16475   S (mp);
16476
16477   /* wait for reply */
16478   W (ret);
16479   return ret;
16480 }
16481
16482 static int
16483 api_show_one_stats_enable_disable (vat_main_t * vam)
16484 {
16485   vl_api_show_one_stats_enable_disable_t *mp;
16486   int ret;
16487
16488   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16489
16490   /* send */
16491   S (mp);
16492
16493   /* wait for reply */
16494   W (ret);
16495   return ret;
16496 }
16497
16498 static int
16499 api_show_one_map_request_mode (vat_main_t * vam)
16500 {
16501   vl_api_show_one_map_request_mode_t *mp;
16502   int ret;
16503
16504   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16505
16506   /* send */
16507   S (mp);
16508
16509   /* wait for reply */
16510   W (ret);
16511   return ret;
16512 }
16513
16514 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16515
16516 static int
16517 api_one_map_request_mode (vat_main_t * vam)
16518 {
16519   unformat_input_t *input = vam->input;
16520   vl_api_one_map_request_mode_t *mp;
16521   u8 mode = 0;
16522   int ret;
16523
16524   /* Parse args required to build the message */
16525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16526     {
16527       if (unformat (input, "dst-only"))
16528         mode = 0;
16529       else if (unformat (input, "src-dst"))
16530         mode = 1;
16531       else
16532         {
16533           errmsg ("parse error '%U'", format_unformat_error, input);
16534           return -99;
16535         }
16536     }
16537
16538   M (ONE_MAP_REQUEST_MODE, mp);
16539
16540   mp->mode = mode;
16541
16542   /* send */
16543   S (mp);
16544
16545   /* wait for reply */
16546   W (ret);
16547   return ret;
16548 }
16549
16550 #define api_lisp_map_request_mode api_one_map_request_mode
16551
16552 /**
16553  * Enable/disable ONE proxy ITR.
16554  *
16555  * @param vam vpp API test context
16556  * @return return code
16557  */
16558 static int
16559 api_one_pitr_set_locator_set (vat_main_t * vam)
16560 {
16561   u8 ls_name_set = 0;
16562   unformat_input_t *input = vam->input;
16563   vl_api_one_pitr_set_locator_set_t *mp;
16564   u8 is_add = 1;
16565   u8 *ls_name = 0;
16566   int ret;
16567
16568   /* Parse args required to build the message */
16569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (input, "del"))
16572         is_add = 0;
16573       else if (unformat (input, "locator-set %s", &ls_name))
16574         ls_name_set = 1;
16575       else
16576         {
16577           errmsg ("parse error '%U'", format_unformat_error, input);
16578           return -99;
16579         }
16580     }
16581
16582   if (!ls_name_set)
16583     {
16584       errmsg ("locator-set name not set!");
16585       return -99;
16586     }
16587
16588   M (ONE_PITR_SET_LOCATOR_SET, mp);
16589
16590   mp->is_add = is_add;
16591   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16592   vec_free (ls_name);
16593
16594   /* send */
16595   S (mp);
16596
16597   /* wait for reply */
16598   W (ret);
16599   return ret;
16600 }
16601
16602 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16603
16604 static int
16605 api_one_nsh_set_locator_set (vat_main_t * vam)
16606 {
16607   u8 ls_name_set = 0;
16608   unformat_input_t *input = vam->input;
16609   vl_api_one_nsh_set_locator_set_t *mp;
16610   u8 is_add = 1;
16611   u8 *ls_name = 0;
16612   int ret;
16613
16614   /* Parse args required to build the message */
16615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (input, "del"))
16618         is_add = 0;
16619       else if (unformat (input, "ls %s", &ls_name))
16620         ls_name_set = 1;
16621       else
16622         {
16623           errmsg ("parse error '%U'", format_unformat_error, input);
16624           return -99;
16625         }
16626     }
16627
16628   if (!ls_name_set && is_add)
16629     {
16630       errmsg ("locator-set name not set!");
16631       return -99;
16632     }
16633
16634   M (ONE_NSH_SET_LOCATOR_SET, mp);
16635
16636   mp->is_add = is_add;
16637   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16638   vec_free (ls_name);
16639
16640   /* send */
16641   S (mp);
16642
16643   /* wait for reply */
16644   W (ret);
16645   return ret;
16646 }
16647
16648 static int
16649 api_show_one_pitr (vat_main_t * vam)
16650 {
16651   vl_api_show_one_pitr_t *mp;
16652   int ret;
16653
16654   if (!vam->json_output)
16655     {
16656       print (vam->ofp, "%=20s", "lisp status:");
16657     }
16658
16659   M (SHOW_ONE_PITR, mp);
16660   /* send it... */
16661   S (mp);
16662
16663   /* Wait for a reply... */
16664   W (ret);
16665   return ret;
16666 }
16667
16668 #define api_show_lisp_pitr api_show_one_pitr
16669
16670 static int
16671 api_one_use_petr (vat_main_t * vam)
16672 {
16673   unformat_input_t *input = vam->input;
16674   vl_api_one_use_petr_t *mp;
16675   u8 is_add = 0;
16676   ip_address_t ip;
16677   int ret;
16678
16679   clib_memset (&ip, 0, sizeof (ip));
16680
16681   /* Parse args required to build the message */
16682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16683     {
16684       if (unformat (input, "disable"))
16685         is_add = 0;
16686       else
16687         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16688         {
16689           is_add = 1;
16690           ip_addr_version (&ip) = IP4;
16691         }
16692       else
16693         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16694         {
16695           is_add = 1;
16696           ip_addr_version (&ip) = IP6;
16697         }
16698       else
16699         {
16700           errmsg ("parse error '%U'", format_unformat_error, input);
16701           return -99;
16702         }
16703     }
16704
16705   M (ONE_USE_PETR, mp);
16706
16707   mp->is_add = is_add;
16708   if (is_add)
16709     {
16710       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16711       if (mp->is_ip4)
16712         clib_memcpy (mp->address, &ip, 4);
16713       else
16714         clib_memcpy (mp->address, &ip, 16);
16715     }
16716
16717   /* send */
16718   S (mp);
16719
16720   /* wait for reply */
16721   W (ret);
16722   return ret;
16723 }
16724
16725 #define api_lisp_use_petr api_one_use_petr
16726
16727 static int
16728 api_show_one_nsh_mapping (vat_main_t * vam)
16729 {
16730   vl_api_show_one_use_petr_t *mp;
16731   int ret;
16732
16733   if (!vam->json_output)
16734     {
16735       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16736     }
16737
16738   M (SHOW_ONE_NSH_MAPPING, mp);
16739   /* send it... */
16740   S (mp);
16741
16742   /* Wait for a reply... */
16743   W (ret);
16744   return ret;
16745 }
16746
16747 static int
16748 api_show_one_use_petr (vat_main_t * vam)
16749 {
16750   vl_api_show_one_use_petr_t *mp;
16751   int ret;
16752
16753   if (!vam->json_output)
16754     {
16755       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16756     }
16757
16758   M (SHOW_ONE_USE_PETR, mp);
16759   /* send it... */
16760   S (mp);
16761
16762   /* Wait for a reply... */
16763   W (ret);
16764   return ret;
16765 }
16766
16767 #define api_show_lisp_use_petr api_show_one_use_petr
16768
16769 /**
16770  * Add/delete mapping between vni and vrf
16771  */
16772 static int
16773 api_one_eid_table_add_del_map (vat_main_t * vam)
16774 {
16775   unformat_input_t *input = vam->input;
16776   vl_api_one_eid_table_add_del_map_t *mp;
16777   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16778   u32 vni, vrf, bd_index;
16779   int ret;
16780
16781   /* Parse args required to build the message */
16782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16783     {
16784       if (unformat (input, "del"))
16785         is_add = 0;
16786       else if (unformat (input, "vrf %d", &vrf))
16787         vrf_set = 1;
16788       else if (unformat (input, "bd_index %d", &bd_index))
16789         bd_index_set = 1;
16790       else if (unformat (input, "vni %d", &vni))
16791         vni_set = 1;
16792       else
16793         break;
16794     }
16795
16796   if (!vni_set || (!vrf_set && !bd_index_set))
16797     {
16798       errmsg ("missing arguments!");
16799       return -99;
16800     }
16801
16802   if (vrf_set && bd_index_set)
16803     {
16804       errmsg ("error: both vrf and bd entered!");
16805       return -99;
16806     }
16807
16808   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16809
16810   mp->is_add = is_add;
16811   mp->vni = htonl (vni);
16812   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16813   mp->is_l2 = bd_index_set;
16814
16815   /* send */
16816   S (mp);
16817
16818   /* wait for reply */
16819   W (ret);
16820   return ret;
16821 }
16822
16823 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16824
16825 uword
16826 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16827 {
16828   u32 *action = va_arg (*args, u32 *);
16829   u8 *s = 0;
16830
16831   if (unformat (input, "%s", &s))
16832     {
16833       if (!strcmp ((char *) s, "no-action"))
16834         action[0] = 0;
16835       else if (!strcmp ((char *) s, "natively-forward"))
16836         action[0] = 1;
16837       else if (!strcmp ((char *) s, "send-map-request"))
16838         action[0] = 2;
16839       else if (!strcmp ((char *) s, "drop"))
16840         action[0] = 3;
16841       else
16842         {
16843           clib_warning ("invalid action: '%s'", s);
16844           action[0] = 3;
16845         }
16846     }
16847   else
16848     return 0;
16849
16850   vec_free (s);
16851   return 1;
16852 }
16853
16854 /**
16855  * Add/del remote mapping to/from ONE control plane
16856  *
16857  * @param vam vpp API test context
16858  * @return return code
16859  */
16860 static int
16861 api_one_add_del_remote_mapping (vat_main_t * vam)
16862 {
16863   unformat_input_t *input = vam->input;
16864   vl_api_one_add_del_remote_mapping_t *mp;
16865   u32 vni = 0;
16866   lisp_eid_vat_t _eid, *eid = &_eid;
16867   lisp_eid_vat_t _seid, *seid = &_seid;
16868   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16869   u32 action = ~0, p, w, data_len;
16870   ip4_address_t rloc4;
16871   ip6_address_t rloc6;
16872   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16873   int ret;
16874
16875   clib_memset (&rloc, 0, sizeof (rloc));
16876
16877   /* Parse args required to build the message */
16878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16879     {
16880       if (unformat (input, "del-all"))
16881         {
16882           del_all = 1;
16883         }
16884       else if (unformat (input, "del"))
16885         {
16886           is_add = 0;
16887         }
16888       else if (unformat (input, "add"))
16889         {
16890           is_add = 1;
16891         }
16892       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16893         {
16894           eid_set = 1;
16895         }
16896       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16897         {
16898           seid_set = 1;
16899         }
16900       else if (unformat (input, "vni %d", &vni))
16901         {
16902           ;
16903         }
16904       else if (unformat (input, "p %d w %d", &p, &w))
16905         {
16906           if (!curr_rloc)
16907             {
16908               errmsg ("No RLOC configured for setting priority/weight!");
16909               return -99;
16910             }
16911           curr_rloc->priority = p;
16912           curr_rloc->weight = w;
16913         }
16914       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16915         {
16916           rloc.is_ip4 = 1;
16917           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16918           vec_add1 (rlocs, rloc);
16919           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16920         }
16921       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16922         {
16923           rloc.is_ip4 = 0;
16924           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16925           vec_add1 (rlocs, rloc);
16926           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16927         }
16928       else if (unformat (input, "action %U",
16929                          unformat_negative_mapping_action, &action))
16930         {
16931           ;
16932         }
16933       else
16934         {
16935           clib_warning ("parse error '%U'", format_unformat_error, input);
16936           return -99;
16937         }
16938     }
16939
16940   if (0 == eid_set)
16941     {
16942       errmsg ("missing params!");
16943       return -99;
16944     }
16945
16946   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16947     {
16948       errmsg ("no action set for negative map-reply!");
16949       return -99;
16950     }
16951
16952   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16953
16954   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16955   mp->is_add = is_add;
16956   mp->vni = htonl (vni);
16957   mp->action = (u8) action;
16958   mp->is_src_dst = seid_set;
16959   mp->eid_len = eid->len;
16960   mp->seid_len = seid->len;
16961   mp->del_all = del_all;
16962   mp->eid_type = eid->type;
16963   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16964   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16965
16966   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16967   clib_memcpy (mp->rlocs, rlocs, data_len);
16968   vec_free (rlocs);
16969
16970   /* send it... */
16971   S (mp);
16972
16973   /* Wait for a reply... */
16974   W (ret);
16975   return ret;
16976 }
16977
16978 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16979
16980 /**
16981  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16982  * forwarding entries in data-plane accordingly.
16983  *
16984  * @param vam vpp API test context
16985  * @return return code
16986  */
16987 static int
16988 api_one_add_del_adjacency (vat_main_t * vam)
16989 {
16990   unformat_input_t *input = vam->input;
16991   vl_api_one_add_del_adjacency_t *mp;
16992   u32 vni = 0;
16993   ip4_address_t leid4, reid4;
16994   ip6_address_t leid6, reid6;
16995   u8 reid_mac[6] = { 0 };
16996   u8 leid_mac[6] = { 0 };
16997   u8 reid_type, leid_type;
16998   u32 leid_len = 0, reid_len = 0, len;
16999   u8 is_add = 1;
17000   int ret;
17001
17002   leid_type = reid_type = (u8) ~ 0;
17003
17004   /* Parse args required to build the message */
17005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006     {
17007       if (unformat (input, "del"))
17008         {
17009           is_add = 0;
17010         }
17011       else if (unformat (input, "add"))
17012         {
17013           is_add = 1;
17014         }
17015       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17016                          &reid4, &len))
17017         {
17018           reid_type = 0;        /* ipv4 */
17019           reid_len = len;
17020         }
17021       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17022                          &reid6, &len))
17023         {
17024           reid_type = 1;        /* ipv6 */
17025           reid_len = len;
17026         }
17027       else if (unformat (input, "reid %U", unformat_ethernet_address,
17028                          reid_mac))
17029         {
17030           reid_type = 2;        /* mac */
17031         }
17032       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17033                          &leid4, &len))
17034         {
17035           leid_type = 0;        /* ipv4 */
17036           leid_len = len;
17037         }
17038       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17039                          &leid6, &len))
17040         {
17041           leid_type = 1;        /* ipv6 */
17042           leid_len = len;
17043         }
17044       else if (unformat (input, "leid %U", unformat_ethernet_address,
17045                          leid_mac))
17046         {
17047           leid_type = 2;        /* mac */
17048         }
17049       else if (unformat (input, "vni %d", &vni))
17050         {
17051           ;
17052         }
17053       else
17054         {
17055           errmsg ("parse error '%U'", format_unformat_error, input);
17056           return -99;
17057         }
17058     }
17059
17060   if ((u8) ~ 0 == reid_type)
17061     {
17062       errmsg ("missing params!");
17063       return -99;
17064     }
17065
17066   if (leid_type != reid_type)
17067     {
17068       errmsg ("remote and local EIDs are of different types!");
17069       return -99;
17070     }
17071
17072   M (ONE_ADD_DEL_ADJACENCY, mp);
17073   mp->is_add = is_add;
17074   mp->vni = htonl (vni);
17075   mp->leid_len = leid_len;
17076   mp->reid_len = reid_len;
17077   mp->eid_type = reid_type;
17078
17079   switch (mp->eid_type)
17080     {
17081     case 0:
17082       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17083       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17084       break;
17085     case 1:
17086       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17087       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17088       break;
17089     case 2:
17090       clib_memcpy (mp->leid, leid_mac, 6);
17091       clib_memcpy (mp->reid, reid_mac, 6);
17092       break;
17093     default:
17094       errmsg ("unknown EID type %d!", mp->eid_type);
17095       return 0;
17096     }
17097
17098   /* send it... */
17099   S (mp);
17100
17101   /* Wait for a reply... */
17102   W (ret);
17103   return ret;
17104 }
17105
17106 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17107
17108 uword
17109 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17110 {
17111   u32 *mode = va_arg (*args, u32 *);
17112
17113   if (unformat (input, "lisp"))
17114     *mode = 0;
17115   else if (unformat (input, "vxlan"))
17116     *mode = 1;
17117   else
17118     return 0;
17119
17120   return 1;
17121 }
17122
17123 static int
17124 api_gpe_get_encap_mode (vat_main_t * vam)
17125 {
17126   vl_api_gpe_get_encap_mode_t *mp;
17127   int ret;
17128
17129   /* Construct the API message */
17130   M (GPE_GET_ENCAP_MODE, mp);
17131
17132   /* send it... */
17133   S (mp);
17134
17135   /* Wait for a reply... */
17136   W (ret);
17137   return ret;
17138 }
17139
17140 static int
17141 api_gpe_set_encap_mode (vat_main_t * vam)
17142 {
17143   unformat_input_t *input = vam->input;
17144   vl_api_gpe_set_encap_mode_t *mp;
17145   int ret;
17146   u32 mode = 0;
17147
17148   /* Parse args required to build the message */
17149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17152         ;
17153       else
17154         break;
17155     }
17156
17157   /* Construct the API message */
17158   M (GPE_SET_ENCAP_MODE, mp);
17159
17160   mp->mode = mode;
17161
17162   /* send it... */
17163   S (mp);
17164
17165   /* Wait for a reply... */
17166   W (ret);
17167   return ret;
17168 }
17169
17170 static int
17171 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17172 {
17173   unformat_input_t *input = vam->input;
17174   vl_api_gpe_add_del_iface_t *mp;
17175   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17176   u32 dp_table = 0, vni = 0;
17177   int ret;
17178
17179   /* Parse args required to build the message */
17180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17181     {
17182       if (unformat (input, "up"))
17183         {
17184           action_set = 1;
17185           is_add = 1;
17186         }
17187       else if (unformat (input, "down"))
17188         {
17189           action_set = 1;
17190           is_add = 0;
17191         }
17192       else if (unformat (input, "table_id %d", &dp_table))
17193         {
17194           dp_table_set = 1;
17195         }
17196       else if (unformat (input, "bd_id %d", &dp_table))
17197         {
17198           dp_table_set = 1;
17199           is_l2 = 1;
17200         }
17201       else if (unformat (input, "vni %d", &vni))
17202         {
17203           vni_set = 1;
17204         }
17205       else
17206         break;
17207     }
17208
17209   if (action_set == 0)
17210     {
17211       errmsg ("Action not set");
17212       return -99;
17213     }
17214   if (dp_table_set == 0 || vni_set == 0)
17215     {
17216       errmsg ("vni and dp_table must be set");
17217       return -99;
17218     }
17219
17220   /* Construct the API message */
17221   M (GPE_ADD_DEL_IFACE, mp);
17222
17223   mp->is_add = is_add;
17224   mp->dp_table = clib_host_to_net_u32 (dp_table);
17225   mp->is_l2 = is_l2;
17226   mp->vni = clib_host_to_net_u32 (vni);
17227
17228   /* send it... */
17229   S (mp);
17230
17231   /* Wait for a reply... */
17232   W (ret);
17233   return ret;
17234 }
17235
17236 static int
17237 api_one_map_register_fallback_threshold (vat_main_t * vam)
17238 {
17239   unformat_input_t *input = vam->input;
17240   vl_api_one_map_register_fallback_threshold_t *mp;
17241   u32 value = 0;
17242   u8 is_set = 0;
17243   int ret;
17244
17245   /* Parse args required to build the message */
17246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17247     {
17248       if (unformat (input, "%u", &value))
17249         is_set = 1;
17250       else
17251         {
17252           clib_warning ("parse error '%U'", format_unformat_error, input);
17253           return -99;
17254         }
17255     }
17256
17257   if (!is_set)
17258     {
17259       errmsg ("fallback threshold value is missing!");
17260       return -99;
17261     }
17262
17263   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17264   mp->value = clib_host_to_net_u32 (value);
17265
17266   /* send it... */
17267   S (mp);
17268
17269   /* Wait for a reply... */
17270   W (ret);
17271   return ret;
17272 }
17273
17274 static int
17275 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17276 {
17277   vl_api_show_one_map_register_fallback_threshold_t *mp;
17278   int ret;
17279
17280   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17281
17282   /* send it... */
17283   S (mp);
17284
17285   /* Wait for a reply... */
17286   W (ret);
17287   return ret;
17288 }
17289
17290 uword
17291 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17292 {
17293   u32 *proto = va_arg (*args, u32 *);
17294
17295   if (unformat (input, "udp"))
17296     *proto = 1;
17297   else if (unformat (input, "api"))
17298     *proto = 2;
17299   else
17300     return 0;
17301
17302   return 1;
17303 }
17304
17305 static int
17306 api_one_set_transport_protocol (vat_main_t * vam)
17307 {
17308   unformat_input_t *input = vam->input;
17309   vl_api_one_set_transport_protocol_t *mp;
17310   u8 is_set = 0;
17311   u32 protocol = 0;
17312   int ret;
17313
17314   /* Parse args required to build the message */
17315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17316     {
17317       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17318         is_set = 1;
17319       else
17320         {
17321           clib_warning ("parse error '%U'", format_unformat_error, input);
17322           return -99;
17323         }
17324     }
17325
17326   if (!is_set)
17327     {
17328       errmsg ("Transport protocol missing!");
17329       return -99;
17330     }
17331
17332   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17333   mp->protocol = (u8) protocol;
17334
17335   /* send it... */
17336   S (mp);
17337
17338   /* Wait for a reply... */
17339   W (ret);
17340   return ret;
17341 }
17342
17343 static int
17344 api_one_get_transport_protocol (vat_main_t * vam)
17345 {
17346   vl_api_one_get_transport_protocol_t *mp;
17347   int ret;
17348
17349   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17350
17351   /* send it... */
17352   S (mp);
17353
17354   /* Wait for a reply... */
17355   W (ret);
17356   return ret;
17357 }
17358
17359 static int
17360 api_one_map_register_set_ttl (vat_main_t * vam)
17361 {
17362   unformat_input_t *input = vam->input;
17363   vl_api_one_map_register_set_ttl_t *mp;
17364   u32 ttl = 0;
17365   u8 is_set = 0;
17366   int ret;
17367
17368   /* Parse args required to build the message */
17369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17370     {
17371       if (unformat (input, "%u", &ttl))
17372         is_set = 1;
17373       else
17374         {
17375           clib_warning ("parse error '%U'", format_unformat_error, input);
17376           return -99;
17377         }
17378     }
17379
17380   if (!is_set)
17381     {
17382       errmsg ("TTL value missing!");
17383       return -99;
17384     }
17385
17386   M (ONE_MAP_REGISTER_SET_TTL, mp);
17387   mp->ttl = clib_host_to_net_u32 (ttl);
17388
17389   /* send it... */
17390   S (mp);
17391
17392   /* Wait for a reply... */
17393   W (ret);
17394   return ret;
17395 }
17396
17397 static int
17398 api_show_one_map_register_ttl (vat_main_t * vam)
17399 {
17400   vl_api_show_one_map_register_ttl_t *mp;
17401   int ret;
17402
17403   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17404
17405   /* send it... */
17406   S (mp);
17407
17408   /* Wait for a reply... */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 /**
17414  * Add/del map request itr rlocs from ONE control plane and updates
17415  *
17416  * @param vam vpp API test context
17417  * @return return code
17418  */
17419 static int
17420 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17421 {
17422   unformat_input_t *input = vam->input;
17423   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17424   u8 *locator_set_name = 0;
17425   u8 locator_set_name_set = 0;
17426   u8 is_add = 1;
17427   int ret;
17428
17429   /* Parse args required to build the message */
17430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17431     {
17432       if (unformat (input, "del"))
17433         {
17434           is_add = 0;
17435         }
17436       else if (unformat (input, "%_%v%_", &locator_set_name))
17437         {
17438           locator_set_name_set = 1;
17439         }
17440       else
17441         {
17442           clib_warning ("parse error '%U'", format_unformat_error, input);
17443           return -99;
17444         }
17445     }
17446
17447   if (is_add && !locator_set_name_set)
17448     {
17449       errmsg ("itr-rloc is not set!");
17450       return -99;
17451     }
17452
17453   if (is_add && vec_len (locator_set_name) > 64)
17454     {
17455       errmsg ("itr-rloc locator-set name too long");
17456       vec_free (locator_set_name);
17457       return -99;
17458     }
17459
17460   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17461   mp->is_add = is_add;
17462   if (is_add)
17463     {
17464       clib_memcpy (mp->locator_set_name, locator_set_name,
17465                    vec_len (locator_set_name));
17466     }
17467   else
17468     {
17469       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17470     }
17471   vec_free (locator_set_name);
17472
17473   /* send it... */
17474   S (mp);
17475
17476   /* Wait for a reply... */
17477   W (ret);
17478   return ret;
17479 }
17480
17481 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17482
17483 static int
17484 api_one_locator_dump (vat_main_t * vam)
17485 {
17486   unformat_input_t *input = vam->input;
17487   vl_api_one_locator_dump_t *mp;
17488   vl_api_control_ping_t *mp_ping;
17489   u8 is_index_set = 0, is_name_set = 0;
17490   u8 *ls_name = 0;
17491   u32 ls_index = ~0;
17492   int ret;
17493
17494   /* Parse args required to build the message */
17495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17496     {
17497       if (unformat (input, "ls_name %_%v%_", &ls_name))
17498         {
17499           is_name_set = 1;
17500         }
17501       else if (unformat (input, "ls_index %d", &ls_index))
17502         {
17503           is_index_set = 1;
17504         }
17505       else
17506         {
17507           errmsg ("parse error '%U'", format_unformat_error, input);
17508           return -99;
17509         }
17510     }
17511
17512   if (!is_index_set && !is_name_set)
17513     {
17514       errmsg ("error: expected one of index or name!");
17515       return -99;
17516     }
17517
17518   if (is_index_set && is_name_set)
17519     {
17520       errmsg ("error: only one param expected!");
17521       return -99;
17522     }
17523
17524   if (vec_len (ls_name) > 62)
17525     {
17526       errmsg ("error: locator set name too long!");
17527       return -99;
17528     }
17529
17530   if (!vam->json_output)
17531     {
17532       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17533     }
17534
17535   M (ONE_LOCATOR_DUMP, mp);
17536   mp->is_index_set = is_index_set;
17537
17538   if (is_index_set)
17539     mp->ls_index = clib_host_to_net_u32 (ls_index);
17540   else
17541     {
17542       vec_add1 (ls_name, 0);
17543       strncpy ((char *) mp->ls_name, (char *) ls_name,
17544                sizeof (mp->ls_name) - 1);
17545     }
17546
17547   /* send it... */
17548   S (mp);
17549
17550   /* Use a control ping for synchronization */
17551   MPING (CONTROL_PING, mp_ping);
17552   S (mp_ping);
17553
17554   /* Wait for a reply... */
17555   W (ret);
17556   return ret;
17557 }
17558
17559 #define api_lisp_locator_dump api_one_locator_dump
17560
17561 static int
17562 api_one_locator_set_dump (vat_main_t * vam)
17563 {
17564   vl_api_one_locator_set_dump_t *mp;
17565   vl_api_control_ping_t *mp_ping;
17566   unformat_input_t *input = vam->input;
17567   u8 filter = 0;
17568   int ret;
17569
17570   /* Parse args required to build the message */
17571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17572     {
17573       if (unformat (input, "local"))
17574         {
17575           filter = 1;
17576         }
17577       else if (unformat (input, "remote"))
17578         {
17579           filter = 2;
17580         }
17581       else
17582         {
17583           errmsg ("parse error '%U'", format_unformat_error, input);
17584           return -99;
17585         }
17586     }
17587
17588   if (!vam->json_output)
17589     {
17590       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17591     }
17592
17593   M (ONE_LOCATOR_SET_DUMP, mp);
17594
17595   mp->filter = filter;
17596
17597   /* send it... */
17598   S (mp);
17599
17600   /* Use a control ping for synchronization */
17601   MPING (CONTROL_PING, mp_ping);
17602   S (mp_ping);
17603
17604   /* Wait for a reply... */
17605   W (ret);
17606   return ret;
17607 }
17608
17609 #define api_lisp_locator_set_dump api_one_locator_set_dump
17610
17611 static int
17612 api_one_eid_table_map_dump (vat_main_t * vam)
17613 {
17614   u8 is_l2 = 0;
17615   u8 mode_set = 0;
17616   unformat_input_t *input = vam->input;
17617   vl_api_one_eid_table_map_dump_t *mp;
17618   vl_api_control_ping_t *mp_ping;
17619   int ret;
17620
17621   /* Parse args required to build the message */
17622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17623     {
17624       if (unformat (input, "l2"))
17625         {
17626           is_l2 = 1;
17627           mode_set = 1;
17628         }
17629       else if (unformat (input, "l3"))
17630         {
17631           is_l2 = 0;
17632           mode_set = 1;
17633         }
17634       else
17635         {
17636           errmsg ("parse error '%U'", format_unformat_error, input);
17637           return -99;
17638         }
17639     }
17640
17641   if (!mode_set)
17642     {
17643       errmsg ("expected one of 'l2' or 'l3' parameter!");
17644       return -99;
17645     }
17646
17647   if (!vam->json_output)
17648     {
17649       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17650     }
17651
17652   M (ONE_EID_TABLE_MAP_DUMP, mp);
17653   mp->is_l2 = is_l2;
17654
17655   /* send it... */
17656   S (mp);
17657
17658   /* Use a control ping for synchronization */
17659   MPING (CONTROL_PING, mp_ping);
17660   S (mp_ping);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17668
17669 static int
17670 api_one_eid_table_vni_dump (vat_main_t * vam)
17671 {
17672   vl_api_one_eid_table_vni_dump_t *mp;
17673   vl_api_control_ping_t *mp_ping;
17674   int ret;
17675
17676   if (!vam->json_output)
17677     {
17678       print (vam->ofp, "VNI");
17679     }
17680
17681   M (ONE_EID_TABLE_VNI_DUMP, mp);
17682
17683   /* send it... */
17684   S (mp);
17685
17686   /* Use a control ping for synchronization */
17687   MPING (CONTROL_PING, mp_ping);
17688   S (mp_ping);
17689
17690   /* Wait for a reply... */
17691   W (ret);
17692   return ret;
17693 }
17694
17695 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17696
17697 static int
17698 api_one_eid_table_dump (vat_main_t * vam)
17699 {
17700   unformat_input_t *i = vam->input;
17701   vl_api_one_eid_table_dump_t *mp;
17702   vl_api_control_ping_t *mp_ping;
17703   struct in_addr ip4;
17704   struct in6_addr ip6;
17705   u8 mac[6];
17706   u8 eid_type = ~0, eid_set = 0;
17707   u32 prefix_length = ~0, t, vni = 0;
17708   u8 filter = 0;
17709   int ret;
17710   lisp_nsh_api_t nsh;
17711
17712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17713     {
17714       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17715         {
17716           eid_set = 1;
17717           eid_type = 0;
17718           prefix_length = t;
17719         }
17720       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17721         {
17722           eid_set = 1;
17723           eid_type = 1;
17724           prefix_length = t;
17725         }
17726       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17727         {
17728           eid_set = 1;
17729           eid_type = 2;
17730         }
17731       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17732         {
17733           eid_set = 1;
17734           eid_type = 3;
17735         }
17736       else if (unformat (i, "vni %d", &t))
17737         {
17738           vni = t;
17739         }
17740       else if (unformat (i, "local"))
17741         {
17742           filter = 1;
17743         }
17744       else if (unformat (i, "remote"))
17745         {
17746           filter = 2;
17747         }
17748       else
17749         {
17750           errmsg ("parse error '%U'", format_unformat_error, i);
17751           return -99;
17752         }
17753     }
17754
17755   if (!vam->json_output)
17756     {
17757       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17758              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17759     }
17760
17761   M (ONE_EID_TABLE_DUMP, mp);
17762
17763   mp->filter = filter;
17764   if (eid_set)
17765     {
17766       mp->eid_set = 1;
17767       mp->vni = htonl (vni);
17768       mp->eid_type = eid_type;
17769       switch (eid_type)
17770         {
17771         case 0:
17772           mp->prefix_length = prefix_length;
17773           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17774           break;
17775         case 1:
17776           mp->prefix_length = prefix_length;
17777           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17778           break;
17779         case 2:
17780           clib_memcpy (mp->eid, mac, sizeof (mac));
17781           break;
17782         case 3:
17783           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17784           break;
17785         default:
17786           errmsg ("unknown EID type %d!", eid_type);
17787           return -99;
17788         }
17789     }
17790
17791   /* send it... */
17792   S (mp);
17793
17794   /* Use a control ping for synchronization */
17795   MPING (CONTROL_PING, mp_ping);
17796   S (mp_ping);
17797
17798   /* Wait for a reply... */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_lisp_eid_table_dump api_one_eid_table_dump
17804
17805 static int
17806 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17807 {
17808   unformat_input_t *i = vam->input;
17809   vl_api_gpe_fwd_entries_get_t *mp;
17810   u8 vni_set = 0;
17811   u32 vni = ~0;
17812   int ret;
17813
17814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (i, "vni %d", &vni))
17817         {
17818           vni_set = 1;
17819         }
17820       else
17821         {
17822           errmsg ("parse error '%U'", format_unformat_error, i);
17823           return -99;
17824         }
17825     }
17826
17827   if (!vni_set)
17828     {
17829       errmsg ("vni not set!");
17830       return -99;
17831     }
17832
17833   if (!vam->json_output)
17834     {
17835       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17836              "leid", "reid");
17837     }
17838
17839   M (GPE_FWD_ENTRIES_GET, mp);
17840   mp->vni = clib_host_to_net_u32 (vni);
17841
17842   /* send it... */
17843   S (mp);
17844
17845   /* Wait for a reply... */
17846   W (ret);
17847   return ret;
17848 }
17849
17850 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17851 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17852 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17853 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17854 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17855 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17856 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17857 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17858
17859 static int
17860 api_one_adjacencies_get (vat_main_t * vam)
17861 {
17862   unformat_input_t *i = vam->input;
17863   vl_api_one_adjacencies_get_t *mp;
17864   u8 vni_set = 0;
17865   u32 vni = ~0;
17866   int ret;
17867
17868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17869     {
17870       if (unformat (i, "vni %d", &vni))
17871         {
17872           vni_set = 1;
17873         }
17874       else
17875         {
17876           errmsg ("parse error '%U'", format_unformat_error, i);
17877           return -99;
17878         }
17879     }
17880
17881   if (!vni_set)
17882     {
17883       errmsg ("vni not set!");
17884       return -99;
17885     }
17886
17887   if (!vam->json_output)
17888     {
17889       print (vam->ofp, "%s %40s", "leid", "reid");
17890     }
17891
17892   M (ONE_ADJACENCIES_GET, mp);
17893   mp->vni = clib_host_to_net_u32 (vni);
17894
17895   /* send it... */
17896   S (mp);
17897
17898   /* Wait for a reply... */
17899   W (ret);
17900   return ret;
17901 }
17902
17903 #define api_lisp_adjacencies_get api_one_adjacencies_get
17904
17905 static int
17906 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17907 {
17908   unformat_input_t *i = vam->input;
17909   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17910   int ret;
17911   u8 ip_family_set = 0, is_ip4 = 1;
17912
17913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17914     {
17915       if (unformat (i, "ip4"))
17916         {
17917           ip_family_set = 1;
17918           is_ip4 = 1;
17919         }
17920       else if (unformat (i, "ip6"))
17921         {
17922           ip_family_set = 1;
17923           is_ip4 = 0;
17924         }
17925       else
17926         {
17927           errmsg ("parse error '%U'", format_unformat_error, i);
17928           return -99;
17929         }
17930     }
17931
17932   if (!ip_family_set)
17933     {
17934       errmsg ("ip family not set!");
17935       return -99;
17936     }
17937
17938   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17939   mp->is_ip4 = is_ip4;
17940
17941   /* send it... */
17942   S (mp);
17943
17944   /* Wait for a reply... */
17945   W (ret);
17946   return ret;
17947 }
17948
17949 static int
17950 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17951 {
17952   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17953   int ret;
17954
17955   if (!vam->json_output)
17956     {
17957       print (vam->ofp, "VNIs");
17958     }
17959
17960   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17961
17962   /* send it... */
17963   S (mp);
17964
17965   /* Wait for a reply... */
17966   W (ret);
17967   return ret;
17968 }
17969
17970 static int
17971 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17972 {
17973   unformat_input_t *i = vam->input;
17974   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17975   int ret = 0;
17976   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17977   struct in_addr ip4;
17978   struct in6_addr ip6;
17979   u32 table_id = 0, nh_sw_if_index = ~0;
17980
17981   clib_memset (&ip4, 0, sizeof (ip4));
17982   clib_memset (&ip6, 0, sizeof (ip6));
17983
17984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17985     {
17986       if (unformat (i, "del"))
17987         is_add = 0;
17988       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17989                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17990         {
17991           ip_set = 1;
17992           is_ip4 = 1;
17993         }
17994       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17995                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17996         {
17997           ip_set = 1;
17998           is_ip4 = 0;
17999         }
18000       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18001         {
18002           ip_set = 1;
18003           is_ip4 = 1;
18004           nh_sw_if_index = ~0;
18005         }
18006       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18007         {
18008           ip_set = 1;
18009           is_ip4 = 0;
18010           nh_sw_if_index = ~0;
18011         }
18012       else if (unformat (i, "table %d", &table_id))
18013         ;
18014       else
18015         {
18016           errmsg ("parse error '%U'", format_unformat_error, i);
18017           return -99;
18018         }
18019     }
18020
18021   if (!ip_set)
18022     {
18023       errmsg ("nh addr not set!");
18024       return -99;
18025     }
18026
18027   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18028   mp->is_add = is_add;
18029   mp->table_id = clib_host_to_net_u32 (table_id);
18030   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18031   mp->is_ip4 = is_ip4;
18032   if (is_ip4)
18033     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18034   else
18035     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18036
18037   /* send it... */
18038   S (mp);
18039
18040   /* Wait for a reply... */
18041   W (ret);
18042   return ret;
18043 }
18044
18045 static int
18046 api_one_map_server_dump (vat_main_t * vam)
18047 {
18048   vl_api_one_map_server_dump_t *mp;
18049   vl_api_control_ping_t *mp_ping;
18050   int ret;
18051
18052   if (!vam->json_output)
18053     {
18054       print (vam->ofp, "%=20s", "Map server");
18055     }
18056
18057   M (ONE_MAP_SERVER_DUMP, mp);
18058   /* send it... */
18059   S (mp);
18060
18061   /* Use a control ping for synchronization */
18062   MPING (CONTROL_PING, mp_ping);
18063   S (mp_ping);
18064
18065   /* Wait for a reply... */
18066   W (ret);
18067   return ret;
18068 }
18069
18070 #define api_lisp_map_server_dump api_one_map_server_dump
18071
18072 static int
18073 api_one_map_resolver_dump (vat_main_t * vam)
18074 {
18075   vl_api_one_map_resolver_dump_t *mp;
18076   vl_api_control_ping_t *mp_ping;
18077   int ret;
18078
18079   if (!vam->json_output)
18080     {
18081       print (vam->ofp, "%=20s", "Map resolver");
18082     }
18083
18084   M (ONE_MAP_RESOLVER_DUMP, mp);
18085   /* send it... */
18086   S (mp);
18087
18088   /* Use a control ping for synchronization */
18089   MPING (CONTROL_PING, mp_ping);
18090   S (mp_ping);
18091
18092   /* Wait for a reply... */
18093   W (ret);
18094   return ret;
18095 }
18096
18097 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18098
18099 static int
18100 api_one_stats_flush (vat_main_t * vam)
18101 {
18102   vl_api_one_stats_flush_t *mp;
18103   int ret = 0;
18104
18105   M (ONE_STATS_FLUSH, mp);
18106   S (mp);
18107   W (ret);
18108   return ret;
18109 }
18110
18111 static int
18112 api_one_stats_dump (vat_main_t * vam)
18113 {
18114   vl_api_one_stats_dump_t *mp;
18115   vl_api_control_ping_t *mp_ping;
18116   int ret;
18117
18118   M (ONE_STATS_DUMP, mp);
18119   /* send it... */
18120   S (mp);
18121
18122   /* Use a control ping for synchronization */
18123   MPING (CONTROL_PING, mp_ping);
18124   S (mp_ping);
18125
18126   /* Wait for a reply... */
18127   W (ret);
18128   return ret;
18129 }
18130
18131 static int
18132 api_show_one_status (vat_main_t * vam)
18133 {
18134   vl_api_show_one_status_t *mp;
18135   int ret;
18136
18137   if (!vam->json_output)
18138     {
18139       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18140     }
18141
18142   M (SHOW_ONE_STATUS, mp);
18143   /* send it... */
18144   S (mp);
18145   /* Wait for a reply... */
18146   W (ret);
18147   return ret;
18148 }
18149
18150 #define api_show_lisp_status api_show_one_status
18151
18152 static int
18153 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18154 {
18155   vl_api_gpe_fwd_entry_path_dump_t *mp;
18156   vl_api_control_ping_t *mp_ping;
18157   unformat_input_t *i = vam->input;
18158   u32 fwd_entry_index = ~0;
18159   int ret;
18160
18161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18162     {
18163       if (unformat (i, "index %d", &fwd_entry_index))
18164         ;
18165       else
18166         break;
18167     }
18168
18169   if (~0 == fwd_entry_index)
18170     {
18171       errmsg ("no index specified!");
18172       return -99;
18173     }
18174
18175   if (!vam->json_output)
18176     {
18177       print (vam->ofp, "first line");
18178     }
18179
18180   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18181
18182   /* send it... */
18183   S (mp);
18184   /* Use a control ping for synchronization */
18185   MPING (CONTROL_PING, mp_ping);
18186   S (mp_ping);
18187
18188   /* Wait for a reply... */
18189   W (ret);
18190   return ret;
18191 }
18192
18193 static int
18194 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18195 {
18196   vl_api_one_get_map_request_itr_rlocs_t *mp;
18197   int ret;
18198
18199   if (!vam->json_output)
18200     {
18201       print (vam->ofp, "%=20s", "itr-rlocs:");
18202     }
18203
18204   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18205   /* send it... */
18206   S (mp);
18207   /* Wait for a reply... */
18208   W (ret);
18209   return ret;
18210 }
18211
18212 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18213
18214 static int
18215 api_af_packet_create (vat_main_t * vam)
18216 {
18217   unformat_input_t *i = vam->input;
18218   vl_api_af_packet_create_t *mp;
18219   u8 *host_if_name = 0;
18220   u8 hw_addr[6];
18221   u8 random_hw_addr = 1;
18222   int ret;
18223
18224   clib_memset (hw_addr, 0, sizeof (hw_addr));
18225
18226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18227     {
18228       if (unformat (i, "name %s", &host_if_name))
18229         vec_add1 (host_if_name, 0);
18230       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18231         random_hw_addr = 0;
18232       else
18233         break;
18234     }
18235
18236   if (!vec_len (host_if_name))
18237     {
18238       errmsg ("host-interface name must be specified");
18239       return -99;
18240     }
18241
18242   if (vec_len (host_if_name) > 64)
18243     {
18244       errmsg ("host-interface name too long");
18245       return -99;
18246     }
18247
18248   M (AF_PACKET_CREATE, mp);
18249
18250   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18251   clib_memcpy (mp->hw_addr, hw_addr, 6);
18252   mp->use_random_hw_addr = random_hw_addr;
18253   vec_free (host_if_name);
18254
18255   S (mp);
18256
18257   /* *INDENT-OFF* */
18258   W2 (ret,
18259       ({
18260         if (ret == 0)
18261           fprintf (vam->ofp ? vam->ofp : stderr,
18262                    " new sw_if_index = %d\n", vam->sw_if_index);
18263       }));
18264   /* *INDENT-ON* */
18265   return ret;
18266 }
18267
18268 static int
18269 api_af_packet_delete (vat_main_t * vam)
18270 {
18271   unformat_input_t *i = vam->input;
18272   vl_api_af_packet_delete_t *mp;
18273   u8 *host_if_name = 0;
18274   int ret;
18275
18276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18277     {
18278       if (unformat (i, "name %s", &host_if_name))
18279         vec_add1 (host_if_name, 0);
18280       else
18281         break;
18282     }
18283
18284   if (!vec_len (host_if_name))
18285     {
18286       errmsg ("host-interface name must be specified");
18287       return -99;
18288     }
18289
18290   if (vec_len (host_if_name) > 64)
18291     {
18292       errmsg ("host-interface name too long");
18293       return -99;
18294     }
18295
18296   M (AF_PACKET_DELETE, mp);
18297
18298   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18299   vec_free (host_if_name);
18300
18301   S (mp);
18302   W (ret);
18303   return ret;
18304 }
18305
18306 static void vl_api_af_packet_details_t_handler
18307   (vl_api_af_packet_details_t * mp)
18308 {
18309   vat_main_t *vam = &vat_main;
18310
18311   print (vam->ofp, "%-16s %d",
18312          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18313 }
18314
18315 static void vl_api_af_packet_details_t_handler_json
18316   (vl_api_af_packet_details_t * mp)
18317 {
18318   vat_main_t *vam = &vat_main;
18319   vat_json_node_t *node = NULL;
18320
18321   if (VAT_JSON_ARRAY != vam->json_tree.type)
18322     {
18323       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18324       vat_json_init_array (&vam->json_tree);
18325     }
18326   node = vat_json_array_add (&vam->json_tree);
18327
18328   vat_json_init_object (node);
18329   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18330   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18331 }
18332
18333 static int
18334 api_af_packet_dump (vat_main_t * vam)
18335 {
18336   vl_api_af_packet_dump_t *mp;
18337   vl_api_control_ping_t *mp_ping;
18338   int ret;
18339
18340   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18341   /* Get list of tap interfaces */
18342   M (AF_PACKET_DUMP, mp);
18343   S (mp);
18344
18345   /* Use a control ping for synchronization */
18346   MPING (CONTROL_PING, mp_ping);
18347   S (mp_ping);
18348
18349   W (ret);
18350   return ret;
18351 }
18352
18353 static int
18354 api_policer_add_del (vat_main_t * vam)
18355 {
18356   unformat_input_t *i = vam->input;
18357   vl_api_policer_add_del_t *mp;
18358   u8 is_add = 1;
18359   u8 *name = 0;
18360   u32 cir = 0;
18361   u32 eir = 0;
18362   u64 cb = 0;
18363   u64 eb = 0;
18364   u8 rate_type = 0;
18365   u8 round_type = 0;
18366   u8 type = 0;
18367   u8 color_aware = 0;
18368   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18369   int ret;
18370
18371   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18372   conform_action.dscp = 0;
18373   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18374   exceed_action.dscp = 0;
18375   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18376   violate_action.dscp = 0;
18377
18378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18379     {
18380       if (unformat (i, "del"))
18381         is_add = 0;
18382       else if (unformat (i, "name %s", &name))
18383         vec_add1 (name, 0);
18384       else if (unformat (i, "cir %u", &cir))
18385         ;
18386       else if (unformat (i, "eir %u", &eir))
18387         ;
18388       else if (unformat (i, "cb %u", &cb))
18389         ;
18390       else if (unformat (i, "eb %u", &eb))
18391         ;
18392       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18393                          &rate_type))
18394         ;
18395       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18396                          &round_type))
18397         ;
18398       else if (unformat (i, "type %U", unformat_policer_type, &type))
18399         ;
18400       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18401                          &conform_action))
18402         ;
18403       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18404                          &exceed_action))
18405         ;
18406       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18407                          &violate_action))
18408         ;
18409       else if (unformat (i, "color-aware"))
18410         color_aware = 1;
18411       else
18412         break;
18413     }
18414
18415   if (!vec_len (name))
18416     {
18417       errmsg ("policer name must be specified");
18418       return -99;
18419     }
18420
18421   if (vec_len (name) > 64)
18422     {
18423       errmsg ("policer name too long");
18424       return -99;
18425     }
18426
18427   M (POLICER_ADD_DEL, mp);
18428
18429   clib_memcpy (mp->name, name, vec_len (name));
18430   vec_free (name);
18431   mp->is_add = is_add;
18432   mp->cir = ntohl (cir);
18433   mp->eir = ntohl (eir);
18434   mp->cb = clib_net_to_host_u64 (cb);
18435   mp->eb = clib_net_to_host_u64 (eb);
18436   mp->rate_type = rate_type;
18437   mp->round_type = round_type;
18438   mp->type = type;
18439   mp->conform_action_type = conform_action.action_type;
18440   mp->conform_dscp = conform_action.dscp;
18441   mp->exceed_action_type = exceed_action.action_type;
18442   mp->exceed_dscp = exceed_action.dscp;
18443   mp->violate_action_type = violate_action.action_type;
18444   mp->violate_dscp = violate_action.dscp;
18445   mp->color_aware = color_aware;
18446
18447   S (mp);
18448   W (ret);
18449   return ret;
18450 }
18451
18452 static int
18453 api_policer_dump (vat_main_t * vam)
18454 {
18455   unformat_input_t *i = vam->input;
18456   vl_api_policer_dump_t *mp;
18457   vl_api_control_ping_t *mp_ping;
18458   u8 *match_name = 0;
18459   u8 match_name_valid = 0;
18460   int ret;
18461
18462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18463     {
18464       if (unformat (i, "name %s", &match_name))
18465         {
18466           vec_add1 (match_name, 0);
18467           match_name_valid = 1;
18468         }
18469       else
18470         break;
18471     }
18472
18473   M (POLICER_DUMP, mp);
18474   mp->match_name_valid = match_name_valid;
18475   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18476   vec_free (match_name);
18477   /* send it... */
18478   S (mp);
18479
18480   /* Use a control ping for synchronization */
18481   MPING (CONTROL_PING, mp_ping);
18482   S (mp_ping);
18483
18484   /* Wait for a reply... */
18485   W (ret);
18486   return ret;
18487 }
18488
18489 static int
18490 api_policer_classify_set_interface (vat_main_t * vam)
18491 {
18492   unformat_input_t *i = vam->input;
18493   vl_api_policer_classify_set_interface_t *mp;
18494   u32 sw_if_index;
18495   int sw_if_index_set;
18496   u32 ip4_table_index = ~0;
18497   u32 ip6_table_index = ~0;
18498   u32 l2_table_index = ~0;
18499   u8 is_add = 1;
18500   int ret;
18501
18502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18503     {
18504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18505         sw_if_index_set = 1;
18506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18507         sw_if_index_set = 1;
18508       else if (unformat (i, "del"))
18509         is_add = 0;
18510       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18511         ;
18512       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18513         ;
18514       else if (unformat (i, "l2-table %d", &l2_table_index))
18515         ;
18516       else
18517         {
18518           clib_warning ("parse error '%U'", format_unformat_error, i);
18519           return -99;
18520         }
18521     }
18522
18523   if (sw_if_index_set == 0)
18524     {
18525       errmsg ("missing interface name or sw_if_index");
18526       return -99;
18527     }
18528
18529   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18530
18531   mp->sw_if_index = ntohl (sw_if_index);
18532   mp->ip4_table_index = ntohl (ip4_table_index);
18533   mp->ip6_table_index = ntohl (ip6_table_index);
18534   mp->l2_table_index = ntohl (l2_table_index);
18535   mp->is_add = is_add;
18536
18537   S (mp);
18538   W (ret);
18539   return ret;
18540 }
18541
18542 static int
18543 api_policer_classify_dump (vat_main_t * vam)
18544 {
18545   unformat_input_t *i = vam->input;
18546   vl_api_policer_classify_dump_t *mp;
18547   vl_api_control_ping_t *mp_ping;
18548   u8 type = POLICER_CLASSIFY_N_TABLES;
18549   int ret;
18550
18551   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18552     ;
18553   else
18554     {
18555       errmsg ("classify table type must be specified");
18556       return -99;
18557     }
18558
18559   if (!vam->json_output)
18560     {
18561       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18562     }
18563
18564   M (POLICER_CLASSIFY_DUMP, mp);
18565   mp->type = type;
18566   /* send it... */
18567   S (mp);
18568
18569   /* Use a control ping for synchronization */
18570   MPING (CONTROL_PING, mp_ping);
18571   S (mp_ping);
18572
18573   /* Wait for a reply... */
18574   W (ret);
18575   return ret;
18576 }
18577
18578 static int
18579 api_netmap_create (vat_main_t * vam)
18580 {
18581   unformat_input_t *i = vam->input;
18582   vl_api_netmap_create_t *mp;
18583   u8 *if_name = 0;
18584   u8 hw_addr[6];
18585   u8 random_hw_addr = 1;
18586   u8 is_pipe = 0;
18587   u8 is_master = 0;
18588   int ret;
18589
18590   clib_memset (hw_addr, 0, sizeof (hw_addr));
18591
18592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18593     {
18594       if (unformat (i, "name %s", &if_name))
18595         vec_add1 (if_name, 0);
18596       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18597         random_hw_addr = 0;
18598       else if (unformat (i, "pipe"))
18599         is_pipe = 1;
18600       else if (unformat (i, "master"))
18601         is_master = 1;
18602       else if (unformat (i, "slave"))
18603         is_master = 0;
18604       else
18605         break;
18606     }
18607
18608   if (!vec_len (if_name))
18609     {
18610       errmsg ("interface name must be specified");
18611       return -99;
18612     }
18613
18614   if (vec_len (if_name) > 64)
18615     {
18616       errmsg ("interface name too long");
18617       return -99;
18618     }
18619
18620   M (NETMAP_CREATE, mp);
18621
18622   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18623   clib_memcpy (mp->hw_addr, hw_addr, 6);
18624   mp->use_random_hw_addr = random_hw_addr;
18625   mp->is_pipe = is_pipe;
18626   mp->is_master = is_master;
18627   vec_free (if_name);
18628
18629   S (mp);
18630   W (ret);
18631   return ret;
18632 }
18633
18634 static int
18635 api_netmap_delete (vat_main_t * vam)
18636 {
18637   unformat_input_t *i = vam->input;
18638   vl_api_netmap_delete_t *mp;
18639   u8 *if_name = 0;
18640   int ret;
18641
18642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18643     {
18644       if (unformat (i, "name %s", &if_name))
18645         vec_add1 (if_name, 0);
18646       else
18647         break;
18648     }
18649
18650   if (!vec_len (if_name))
18651     {
18652       errmsg ("interface name must be specified");
18653       return -99;
18654     }
18655
18656   if (vec_len (if_name) > 64)
18657     {
18658       errmsg ("interface name too long");
18659       return -99;
18660     }
18661
18662   M (NETMAP_DELETE, mp);
18663
18664   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18665   vec_free (if_name);
18666
18667   S (mp);
18668   W (ret);
18669   return ret;
18670 }
18671
18672 static u8 *
18673 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18674 {
18675   vl_api_fib_path_nh_proto_t proto =
18676     va_arg (*args, vl_api_fib_path_nh_proto_t);
18677
18678   switch (proto)
18679     {
18680     case FIB_API_PATH_NH_PROTO_IP4:
18681       s = format (s, "ip4");
18682       break;
18683     case FIB_API_PATH_NH_PROTO_IP6:
18684       s = format (s, "ip6");
18685       break;
18686     case FIB_API_PATH_NH_PROTO_MPLS:
18687       s = format (s, "mpls");
18688       break;
18689     case FIB_API_PATH_NH_PROTO_BIER:
18690       s = format (s, "bier");
18691       break;
18692     case FIB_API_PATH_NH_PROTO_ETHERNET:
18693       s = format (s, "ethernet");
18694       break;
18695     }
18696
18697   return (s);
18698 }
18699
18700 static u8 *
18701 format_vl_api_ip_address_union (u8 * s, va_list * args)
18702 {
18703   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18704   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18705
18706   switch (af)
18707     {
18708     case ADDRESS_IP4:
18709       s = format (s, "%U", format_ip4_address, u->ip4);
18710       break;
18711     case ADDRESS_IP6:
18712       s = format (s, "%U", format_ip6_address, u->ip6);
18713       break;
18714     }
18715   return (s);
18716 }
18717
18718 static u8 *
18719 format_vl_api_fib_path_type (u8 * s, va_list * args)
18720 {
18721   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18722
18723   switch (t)
18724     {
18725     case FIB_API_PATH_TYPE_NORMAL:
18726       s = format (s, "normal");
18727       break;
18728     case FIB_API_PATH_TYPE_LOCAL:
18729       s = format (s, "local");
18730       break;
18731     case FIB_API_PATH_TYPE_DROP:
18732       s = format (s, "drop");
18733       break;
18734     case FIB_API_PATH_TYPE_UDP_ENCAP:
18735       s = format (s, "udp-encap");
18736       break;
18737     case FIB_API_PATH_TYPE_BIER_IMP:
18738       s = format (s, "bier-imp");
18739       break;
18740     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18741       s = format (s, "unreach");
18742       break;
18743     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18744       s = format (s, "prohibit");
18745       break;
18746     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18747       s = format (s, "src-lookup");
18748       break;
18749     case FIB_API_PATH_TYPE_DVR:
18750       s = format (s, "dvr");
18751       break;
18752     case FIB_API_PATH_TYPE_INTERFACE_RX:
18753       s = format (s, "interface-rx");
18754       break;
18755     case FIB_API_PATH_TYPE_CLASSIFY:
18756       s = format (s, "classify");
18757       break;
18758     }
18759
18760   return (s);
18761 }
18762
18763 static void
18764 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18765 {
18766   print (vam->ofp,
18767          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18768          ntohl (fp->weight), ntohl (fp->sw_if_index),
18769          format_vl_api_fib_path_type, fp->type,
18770          format_fib_api_path_nh_proto, fp->proto,
18771          format_vl_api_ip_address_union, &fp->nh.address);
18772 }
18773
18774 static void
18775 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18776                                  vl_api_fib_path_t * fp)
18777 {
18778   struct in_addr ip4;
18779   struct in6_addr ip6;
18780
18781   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18782   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18783   vat_json_object_add_uint (node, "type", fp->type);
18784   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18785   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18786     {
18787       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18788       vat_json_object_add_ip4 (node, "next_hop", ip4);
18789     }
18790   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18791     {
18792       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18793       vat_json_object_add_ip6 (node, "next_hop", ip6);
18794     }
18795 }
18796
18797 static void
18798 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18799 {
18800   vat_main_t *vam = &vat_main;
18801   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18802   vl_api_fib_path_t *fp;
18803   i32 i;
18804
18805   print (vam->ofp, "sw_if_index %d via:",
18806          ntohl (mp->mt_tunnel.mt_sw_if_index));
18807   fp = mp->mt_tunnel.mt_paths;
18808   for (i = 0; i < count; i++)
18809     {
18810       vl_api_fib_path_print (vam, fp);
18811       fp++;
18812     }
18813
18814   print (vam->ofp, "");
18815 }
18816
18817 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18818 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18819
18820 static void
18821 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18822 {
18823   vat_main_t *vam = &vat_main;
18824   vat_json_node_t *node = NULL;
18825   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18826   vl_api_fib_path_t *fp;
18827   i32 i;
18828
18829   if (VAT_JSON_ARRAY != vam->json_tree.type)
18830     {
18831       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18832       vat_json_init_array (&vam->json_tree);
18833     }
18834   node = vat_json_array_add (&vam->json_tree);
18835
18836   vat_json_init_object (node);
18837   vat_json_object_add_uint (node, "sw_if_index",
18838                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18839
18840   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18841
18842   fp = mp->mt_tunnel.mt_paths;
18843   for (i = 0; i < count; i++)
18844     {
18845       vl_api_mpls_fib_path_json_print (node, fp);
18846       fp++;
18847     }
18848 }
18849
18850 static int
18851 api_mpls_tunnel_dump (vat_main_t * vam)
18852 {
18853   vl_api_mpls_tunnel_dump_t *mp;
18854   vl_api_control_ping_t *mp_ping;
18855   int ret;
18856
18857   M (MPLS_TUNNEL_DUMP, mp);
18858
18859   S (mp);
18860
18861   /* Use a control ping for synchronization */
18862   MPING (CONTROL_PING, mp_ping);
18863   S (mp_ping);
18864
18865   W (ret);
18866   return ret;
18867 }
18868
18869 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18870 #define vl_api_mpls_table_details_t_print vl_noop_handler
18871
18872
18873 static void
18874 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18875 {
18876   vat_main_t *vam = &vat_main;
18877
18878   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18879 }
18880
18881 static void vl_api_mpls_table_details_t_handler_json
18882   (vl_api_mpls_table_details_t * mp)
18883 {
18884   vat_main_t *vam = &vat_main;
18885   vat_json_node_t *node = NULL;
18886
18887   if (VAT_JSON_ARRAY != vam->json_tree.type)
18888     {
18889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18890       vat_json_init_array (&vam->json_tree);
18891     }
18892   node = vat_json_array_add (&vam->json_tree);
18893
18894   vat_json_init_object (node);
18895   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18896 }
18897
18898 static int
18899 api_mpls_table_dump (vat_main_t * vam)
18900 {
18901   vl_api_mpls_table_dump_t *mp;
18902   vl_api_control_ping_t *mp_ping;
18903   int ret;
18904
18905   M (MPLS_TABLE_DUMP, mp);
18906   S (mp);
18907
18908   /* Use a control ping for synchronization */
18909   MPING (CONTROL_PING, mp_ping);
18910   S (mp_ping);
18911
18912   W (ret);
18913   return ret;
18914 }
18915
18916 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18917 #define vl_api_mpls_route_details_t_print vl_noop_handler
18918
18919 static void
18920 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18921 {
18922   vat_main_t *vam = &vat_main;
18923   int count = ntohl (mp->mr_route.mr_n_paths);
18924   vl_api_fib_path_t *fp;
18925   int i;
18926
18927   print (vam->ofp,
18928          "table-id %d, label %u, ess_bit %u",
18929          ntohl (mp->mr_route.mr_table_id),
18930          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18931   fp = mp->mr_route.mr_paths;
18932   for (i = 0; i < count; i++)
18933     {
18934       vl_api_fib_path_print (vam, fp);
18935       fp++;
18936     }
18937 }
18938
18939 static void vl_api_mpls_route_details_t_handler_json
18940   (vl_api_mpls_route_details_t * mp)
18941 {
18942   vat_main_t *vam = &vat_main;
18943   int count = ntohl (mp->mr_route.mr_n_paths);
18944   vat_json_node_t *node = NULL;
18945   vl_api_fib_path_t *fp;
18946   int i;
18947
18948   if (VAT_JSON_ARRAY != vam->json_tree.type)
18949     {
18950       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18951       vat_json_init_array (&vam->json_tree);
18952     }
18953   node = vat_json_array_add (&vam->json_tree);
18954
18955   vat_json_init_object (node);
18956   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18957   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18958   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18959   vat_json_object_add_uint (node, "path_count", count);
18960   fp = mp->mr_route.mr_paths;
18961   for (i = 0; i < count; i++)
18962     {
18963       vl_api_mpls_fib_path_json_print (node, fp);
18964       fp++;
18965     }
18966 }
18967
18968 static int
18969 api_mpls_route_dump (vat_main_t * vam)
18970 {
18971   unformat_input_t *input = vam->input;
18972   vl_api_mpls_route_dump_t *mp;
18973   vl_api_control_ping_t *mp_ping;
18974   u32 table_id;
18975   int ret;
18976
18977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18978     {
18979       if (unformat (input, "table_id %d", &table_id))
18980         ;
18981       else
18982         break;
18983     }
18984   if (table_id == ~0)
18985     {
18986       errmsg ("missing table id");
18987       return -99;
18988     }
18989
18990   M (MPLS_ROUTE_DUMP, mp);
18991
18992   mp->table.mt_table_id = ntohl (table_id);
18993   S (mp);
18994
18995   /* Use a control ping for synchronization */
18996   MPING (CONTROL_PING, mp_ping);
18997   S (mp_ping);
18998
18999   W (ret);
19000   return ret;
19001 }
19002
19003 #define vl_api_ip_table_details_t_endian vl_noop_handler
19004 #define vl_api_ip_table_details_t_print vl_noop_handler
19005
19006 static void
19007 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19008 {
19009   vat_main_t *vam = &vat_main;
19010
19011   print (vam->ofp,
19012          "%s; table-id %d, prefix %U/%d",
19013          mp->table.name, ntohl (mp->table.table_id));
19014 }
19015
19016
19017 static void vl_api_ip_table_details_t_handler_json
19018   (vl_api_ip_table_details_t * mp)
19019 {
19020   vat_main_t *vam = &vat_main;
19021   vat_json_node_t *node = NULL;
19022
19023   if (VAT_JSON_ARRAY != vam->json_tree.type)
19024     {
19025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19026       vat_json_init_array (&vam->json_tree);
19027     }
19028   node = vat_json_array_add (&vam->json_tree);
19029
19030   vat_json_init_object (node);
19031   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19032 }
19033
19034 static int
19035 api_ip_table_dump (vat_main_t * vam)
19036 {
19037   vl_api_ip_table_dump_t *mp;
19038   vl_api_control_ping_t *mp_ping;
19039   int ret;
19040
19041   M (IP_TABLE_DUMP, mp);
19042   S (mp);
19043
19044   /* Use a control ping for synchronization */
19045   MPING (CONTROL_PING, mp_ping);
19046   S (mp_ping);
19047
19048   W (ret);
19049   return ret;
19050 }
19051
19052 static int
19053 api_ip_mtable_dump (vat_main_t * vam)
19054 {
19055   vl_api_ip_mtable_dump_t *mp;
19056   vl_api_control_ping_t *mp_ping;
19057   int ret;
19058
19059   M (IP_MTABLE_DUMP, mp);
19060   S (mp);
19061
19062   /* Use a control ping for synchronization */
19063   MPING (CONTROL_PING, mp_ping);
19064   S (mp_ping);
19065
19066   W (ret);
19067   return ret;
19068 }
19069
19070 static int
19071 api_ip_mroute_dump (vat_main_t * vam)
19072 {
19073   unformat_input_t *input = vam->input;
19074   vl_api_control_ping_t *mp_ping;
19075   vl_api_ip_mroute_dump_t *mp;
19076   int ret, is_ip6;
19077   u32 table_id;
19078
19079   is_ip6 = 0;
19080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19081     {
19082       if (unformat (input, "table_id %d", &table_id))
19083         ;
19084       else if (unformat (input, "ip6"))
19085         is_ip6 = 1;
19086       else if (unformat (input, "ip4"))
19087         is_ip6 = 0;
19088       else
19089         break;
19090     }
19091   if (table_id == ~0)
19092     {
19093       errmsg ("missing table id");
19094       return -99;
19095     }
19096
19097   M (IP_MROUTE_DUMP, mp);
19098   mp->table.table_id = table_id;
19099   mp->table.is_ip6 = is_ip6;
19100   S (mp);
19101
19102   /* Use a control ping for synchronization */
19103   MPING (CONTROL_PING, mp_ping);
19104   S (mp_ping);
19105
19106   W (ret);
19107   return ret;
19108 }
19109
19110 static void vl_api_ip_neighbor_details_t_handler
19111   (vl_api_ip_neighbor_details_t * mp)
19112 {
19113   vat_main_t *vam = &vat_main;
19114
19115   print (vam->ofp, "%c %U %U",
19116          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19117          format_vl_api_mac_address, &mp->neighbor.mac_address,
19118          format_vl_api_address, &mp->neighbor.ip_address);
19119 }
19120
19121 static void vl_api_ip_neighbor_details_t_handler_json
19122   (vl_api_ip_neighbor_details_t * mp)
19123 {
19124
19125   vat_main_t *vam = &vat_main;
19126   vat_json_node_t *node;
19127
19128   if (VAT_JSON_ARRAY != vam->json_tree.type)
19129     {
19130       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19131       vat_json_init_array (&vam->json_tree);
19132     }
19133   node = vat_json_array_add (&vam->json_tree);
19134
19135   vat_json_init_object (node);
19136   vat_json_object_add_string_copy
19137     (node, "flag",
19138      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19139       (u8 *) "static" : (u8 *) "dynamic"));
19140
19141   vat_json_object_add_string_copy (node, "link_layer",
19142                                    format (0, "%U", format_vl_api_mac_address,
19143                                            &mp->neighbor.mac_address));
19144   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19145 }
19146
19147 static int
19148 api_ip_neighbor_dump (vat_main_t * vam)
19149 {
19150   unformat_input_t *i = vam->input;
19151   vl_api_ip_neighbor_dump_t *mp;
19152   vl_api_control_ping_t *mp_ping;
19153   u8 is_ipv6 = 0;
19154   u32 sw_if_index = ~0;
19155   int ret;
19156
19157   /* Parse args required to build the message */
19158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19159     {
19160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19161         ;
19162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19163         ;
19164       else if (unformat (i, "ip6"))
19165         is_ipv6 = 1;
19166       else
19167         break;
19168     }
19169
19170   if (sw_if_index == ~0)
19171     {
19172       errmsg ("missing interface name or sw_if_index");
19173       return -99;
19174     }
19175
19176   M (IP_NEIGHBOR_DUMP, mp);
19177   mp->is_ipv6 = (u8) is_ipv6;
19178   mp->sw_if_index = ntohl (sw_if_index);
19179   S (mp);
19180
19181   /* Use a control ping for synchronization */
19182   MPING (CONTROL_PING, mp_ping);
19183   S (mp_ping);
19184
19185   W (ret);
19186   return ret;
19187 }
19188
19189 #define vl_api_ip_route_details_t_endian vl_noop_handler
19190 #define vl_api_ip_route_details_t_print vl_noop_handler
19191
19192 static void
19193 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19194 {
19195   vat_main_t *vam = &vat_main;
19196   u8 count = mp->route.n_paths;
19197   vl_api_fib_path_t *fp;
19198   int i;
19199
19200   print (vam->ofp,
19201          "table-id %d, prefix %U/%d",
19202          ntohl (mp->route.table_id),
19203          format_ip46_address,
19204          mp->route.prefix.address, mp->route.prefix.address_length);
19205   for (i = 0; i < count; i++)
19206     {
19207       fp = &mp->route.paths[i];
19208
19209       vl_api_fib_path_print (vam, fp);
19210       fp++;
19211     }
19212 }
19213
19214 static void vl_api_ip_route_details_t_handler_json
19215   (vl_api_ip_route_details_t * mp)
19216 {
19217   vat_main_t *vam = &vat_main;
19218   u8 count = mp->route.n_paths;
19219   vat_json_node_t *node = NULL;
19220   struct in_addr ip4;
19221   struct in6_addr ip6;
19222   vl_api_fib_path_t *fp;
19223   int i;
19224
19225   if (VAT_JSON_ARRAY != vam->json_tree.type)
19226     {
19227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19228       vat_json_init_array (&vam->json_tree);
19229     }
19230   node = vat_json_array_add (&vam->json_tree);
19231
19232   vat_json_init_object (node);
19233   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19234   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19235     {
19236       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19237       vat_json_object_add_ip6 (node, "prefix", ip6);
19238     }
19239   else
19240     {
19241       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19242       vat_json_object_add_ip4 (node, "prefix", ip4);
19243     }
19244   vat_json_object_add_uint (node, "mask_length",
19245                             mp->route.prefix.address_length);
19246   vat_json_object_add_uint (node, "path_count", count);
19247   for (i = 0; i < count; i++)
19248     {
19249       fp = &mp->route.paths[i];
19250       vl_api_mpls_fib_path_json_print (node, fp);
19251     }
19252 }
19253
19254 static int
19255 api_ip_route_dump (vat_main_t * vam)
19256 {
19257   unformat_input_t *input = vam->input;
19258   vl_api_ip_route_dump_t *mp;
19259   vl_api_control_ping_t *mp_ping;
19260   u32 table_id;
19261   u8 is_ip6;
19262   int ret;
19263
19264   is_ip6 = 0;
19265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19266     {
19267       if (unformat (input, "table_id %d", &table_id))
19268         ;
19269       else if (unformat (input, "ip6"))
19270         is_ip6 = 1;
19271       else if (unformat (input, "ip4"))
19272         is_ip6 = 0;
19273       else
19274         break;
19275     }
19276   if (table_id == ~0)
19277     {
19278       errmsg ("missing table id");
19279       return -99;
19280     }
19281
19282   M (IP_ROUTE_DUMP, mp);
19283
19284   mp->table.table_id = table_id;
19285   mp->table.is_ip6 = is_ip6;
19286
19287   S (mp);
19288
19289   /* Use a control ping for synchronization */
19290   MPING (CONTROL_PING, mp_ping);
19291   S (mp_ping);
19292
19293   W (ret);
19294   return ret;
19295 }
19296
19297 int
19298 api_classify_table_ids (vat_main_t * vam)
19299 {
19300   vl_api_classify_table_ids_t *mp;
19301   int ret;
19302
19303   /* Construct the API message */
19304   M (CLASSIFY_TABLE_IDS, mp);
19305   mp->context = 0;
19306
19307   S (mp);
19308   W (ret);
19309   return ret;
19310 }
19311
19312 int
19313 api_classify_table_by_interface (vat_main_t * vam)
19314 {
19315   unformat_input_t *input = vam->input;
19316   vl_api_classify_table_by_interface_t *mp;
19317
19318   u32 sw_if_index = ~0;
19319   int ret;
19320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19321     {
19322       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19323         ;
19324       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19325         ;
19326       else
19327         break;
19328     }
19329   if (sw_if_index == ~0)
19330     {
19331       errmsg ("missing interface name or sw_if_index");
19332       return -99;
19333     }
19334
19335   /* Construct the API message */
19336   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19337   mp->context = 0;
19338   mp->sw_if_index = ntohl (sw_if_index);
19339
19340   S (mp);
19341   W (ret);
19342   return ret;
19343 }
19344
19345 int
19346 api_classify_table_info (vat_main_t * vam)
19347 {
19348   unformat_input_t *input = vam->input;
19349   vl_api_classify_table_info_t *mp;
19350
19351   u32 table_id = ~0;
19352   int ret;
19353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19354     {
19355       if (unformat (input, "table_id %d", &table_id))
19356         ;
19357       else
19358         break;
19359     }
19360   if (table_id == ~0)
19361     {
19362       errmsg ("missing table id");
19363       return -99;
19364     }
19365
19366   /* Construct the API message */
19367   M (CLASSIFY_TABLE_INFO, mp);
19368   mp->context = 0;
19369   mp->table_id = ntohl (table_id);
19370
19371   S (mp);
19372   W (ret);
19373   return ret;
19374 }
19375
19376 int
19377 api_classify_session_dump (vat_main_t * vam)
19378 {
19379   unformat_input_t *input = vam->input;
19380   vl_api_classify_session_dump_t *mp;
19381   vl_api_control_ping_t *mp_ping;
19382
19383   u32 table_id = ~0;
19384   int ret;
19385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19386     {
19387       if (unformat (input, "table_id %d", &table_id))
19388         ;
19389       else
19390         break;
19391     }
19392   if (table_id == ~0)
19393     {
19394       errmsg ("missing table id");
19395       return -99;
19396     }
19397
19398   /* Construct the API message */
19399   M (CLASSIFY_SESSION_DUMP, mp);
19400   mp->context = 0;
19401   mp->table_id = ntohl (table_id);
19402   S (mp);
19403
19404   /* Use a control ping for synchronization */
19405   MPING (CONTROL_PING, mp_ping);
19406   S (mp_ping);
19407
19408   W (ret);
19409   return ret;
19410 }
19411
19412 static void
19413 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19414 {
19415   vat_main_t *vam = &vat_main;
19416
19417   print (vam->ofp, "collector_address %U, collector_port %d, "
19418          "src_address %U, vrf_id %d, path_mtu %u, "
19419          "template_interval %u, udp_checksum %d",
19420          format_ip4_address, mp->collector_address,
19421          ntohs (mp->collector_port),
19422          format_ip4_address, mp->src_address,
19423          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19424          ntohl (mp->template_interval), mp->udp_checksum);
19425
19426   vam->retval = 0;
19427   vam->result_ready = 1;
19428 }
19429
19430 static void
19431   vl_api_ipfix_exporter_details_t_handler_json
19432   (vl_api_ipfix_exporter_details_t * mp)
19433 {
19434   vat_main_t *vam = &vat_main;
19435   vat_json_node_t node;
19436   struct in_addr collector_address;
19437   struct in_addr src_address;
19438
19439   vat_json_init_object (&node);
19440   clib_memcpy (&collector_address, &mp->collector_address,
19441                sizeof (collector_address));
19442   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19443   vat_json_object_add_uint (&node, "collector_port",
19444                             ntohs (mp->collector_port));
19445   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19446   vat_json_object_add_ip4 (&node, "src_address", src_address);
19447   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19448   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19449   vat_json_object_add_uint (&node, "template_interval",
19450                             ntohl (mp->template_interval));
19451   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19452
19453   vat_json_print (vam->ofp, &node);
19454   vat_json_free (&node);
19455   vam->retval = 0;
19456   vam->result_ready = 1;
19457 }
19458
19459 int
19460 api_ipfix_exporter_dump (vat_main_t * vam)
19461 {
19462   vl_api_ipfix_exporter_dump_t *mp;
19463   int ret;
19464
19465   /* Construct the API message */
19466   M (IPFIX_EXPORTER_DUMP, mp);
19467   mp->context = 0;
19468
19469   S (mp);
19470   W (ret);
19471   return ret;
19472 }
19473
19474 static int
19475 api_ipfix_classify_stream_dump (vat_main_t * vam)
19476 {
19477   vl_api_ipfix_classify_stream_dump_t *mp;
19478   int ret;
19479
19480   /* Construct the API message */
19481   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19482   mp->context = 0;
19483
19484   S (mp);
19485   W (ret);
19486   return ret;
19487   /* NOTREACHED */
19488   return 0;
19489 }
19490
19491 static void
19492   vl_api_ipfix_classify_stream_details_t_handler
19493   (vl_api_ipfix_classify_stream_details_t * mp)
19494 {
19495   vat_main_t *vam = &vat_main;
19496   print (vam->ofp, "domain_id %d, src_port %d",
19497          ntohl (mp->domain_id), ntohs (mp->src_port));
19498   vam->retval = 0;
19499   vam->result_ready = 1;
19500 }
19501
19502 static void
19503   vl_api_ipfix_classify_stream_details_t_handler_json
19504   (vl_api_ipfix_classify_stream_details_t * mp)
19505 {
19506   vat_main_t *vam = &vat_main;
19507   vat_json_node_t node;
19508
19509   vat_json_init_object (&node);
19510   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19511   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19512
19513   vat_json_print (vam->ofp, &node);
19514   vat_json_free (&node);
19515   vam->retval = 0;
19516   vam->result_ready = 1;
19517 }
19518
19519 static int
19520 api_ipfix_classify_table_dump (vat_main_t * vam)
19521 {
19522   vl_api_ipfix_classify_table_dump_t *mp;
19523   vl_api_control_ping_t *mp_ping;
19524   int ret;
19525
19526   if (!vam->json_output)
19527     {
19528       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19529              "transport_protocol");
19530     }
19531
19532   /* Construct the API message */
19533   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19534
19535   /* send it... */
19536   S (mp);
19537
19538   /* Use a control ping for synchronization */
19539   MPING (CONTROL_PING, mp_ping);
19540   S (mp_ping);
19541
19542   W (ret);
19543   return ret;
19544 }
19545
19546 static void
19547   vl_api_ipfix_classify_table_details_t_handler
19548   (vl_api_ipfix_classify_table_details_t * mp)
19549 {
19550   vat_main_t *vam = &vat_main;
19551   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19552          mp->transport_protocol);
19553 }
19554
19555 static void
19556   vl_api_ipfix_classify_table_details_t_handler_json
19557   (vl_api_ipfix_classify_table_details_t * mp)
19558 {
19559   vat_json_node_t *node = NULL;
19560   vat_main_t *vam = &vat_main;
19561
19562   if (VAT_JSON_ARRAY != vam->json_tree.type)
19563     {
19564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19565       vat_json_init_array (&vam->json_tree);
19566     }
19567
19568   node = vat_json_array_add (&vam->json_tree);
19569   vat_json_init_object (node);
19570
19571   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19572   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19573   vat_json_object_add_uint (node, "transport_protocol",
19574                             mp->transport_protocol);
19575 }
19576
19577 static int
19578 api_sw_interface_span_enable_disable (vat_main_t * vam)
19579 {
19580   unformat_input_t *i = vam->input;
19581   vl_api_sw_interface_span_enable_disable_t *mp;
19582   u32 src_sw_if_index = ~0;
19583   u32 dst_sw_if_index = ~0;
19584   u8 state = 3;
19585   int ret;
19586   u8 is_l2 = 0;
19587
19588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19589     {
19590       if (unformat
19591           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19592         ;
19593       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19594         ;
19595       else
19596         if (unformat
19597             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19598         ;
19599       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19600         ;
19601       else if (unformat (i, "disable"))
19602         state = 0;
19603       else if (unformat (i, "rx"))
19604         state = 1;
19605       else if (unformat (i, "tx"))
19606         state = 2;
19607       else if (unformat (i, "both"))
19608         state = 3;
19609       else if (unformat (i, "l2"))
19610         is_l2 = 1;
19611       else
19612         break;
19613     }
19614
19615   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19616
19617   mp->sw_if_index_from = htonl (src_sw_if_index);
19618   mp->sw_if_index_to = htonl (dst_sw_if_index);
19619   mp->state = state;
19620   mp->is_l2 = is_l2;
19621
19622   S (mp);
19623   W (ret);
19624   return ret;
19625 }
19626
19627 static void
19628 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19629                                             * mp)
19630 {
19631   vat_main_t *vam = &vat_main;
19632   u8 *sw_if_from_name = 0;
19633   u8 *sw_if_to_name = 0;
19634   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19635   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19636   char *states[] = { "none", "rx", "tx", "both" };
19637   hash_pair_t *p;
19638
19639   /* *INDENT-OFF* */
19640   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19641   ({
19642     if ((u32) p->value[0] == sw_if_index_from)
19643       {
19644         sw_if_from_name = (u8 *)(p->key);
19645         if (sw_if_to_name)
19646           break;
19647       }
19648     if ((u32) p->value[0] == sw_if_index_to)
19649       {
19650         sw_if_to_name = (u8 *)(p->key);
19651         if (sw_if_from_name)
19652           break;
19653       }
19654   }));
19655   /* *INDENT-ON* */
19656   print (vam->ofp, "%20s => %20s (%s) %s",
19657          sw_if_from_name, sw_if_to_name, states[mp->state],
19658          mp->is_l2 ? "l2" : "device");
19659 }
19660
19661 static void
19662   vl_api_sw_interface_span_details_t_handler_json
19663   (vl_api_sw_interface_span_details_t * mp)
19664 {
19665   vat_main_t *vam = &vat_main;
19666   vat_json_node_t *node = NULL;
19667   u8 *sw_if_from_name = 0;
19668   u8 *sw_if_to_name = 0;
19669   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19670   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19671   hash_pair_t *p;
19672
19673   /* *INDENT-OFF* */
19674   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19675   ({
19676     if ((u32) p->value[0] == sw_if_index_from)
19677       {
19678         sw_if_from_name = (u8 *)(p->key);
19679         if (sw_if_to_name)
19680           break;
19681       }
19682     if ((u32) p->value[0] == sw_if_index_to)
19683       {
19684         sw_if_to_name = (u8 *)(p->key);
19685         if (sw_if_from_name)
19686           break;
19687       }
19688   }));
19689   /* *INDENT-ON* */
19690
19691   if (VAT_JSON_ARRAY != vam->json_tree.type)
19692     {
19693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19694       vat_json_init_array (&vam->json_tree);
19695     }
19696   node = vat_json_array_add (&vam->json_tree);
19697
19698   vat_json_init_object (node);
19699   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19700   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19701   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19702   if (0 != sw_if_to_name)
19703     {
19704       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19705     }
19706   vat_json_object_add_uint (node, "state", mp->state);
19707   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19708 }
19709
19710 static int
19711 api_sw_interface_span_dump (vat_main_t * vam)
19712 {
19713   unformat_input_t *input = vam->input;
19714   vl_api_sw_interface_span_dump_t *mp;
19715   vl_api_control_ping_t *mp_ping;
19716   u8 is_l2 = 0;
19717   int ret;
19718
19719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (input, "l2"))
19722         is_l2 = 1;
19723       else
19724         break;
19725     }
19726
19727   M (SW_INTERFACE_SPAN_DUMP, mp);
19728   mp->is_l2 = is_l2;
19729   S (mp);
19730
19731   /* Use a control ping for synchronization */
19732   MPING (CONTROL_PING, mp_ping);
19733   S (mp_ping);
19734
19735   W (ret);
19736   return ret;
19737 }
19738
19739 int
19740 api_pg_create_interface (vat_main_t * vam)
19741 {
19742   unformat_input_t *input = vam->input;
19743   vl_api_pg_create_interface_t *mp;
19744
19745   u32 if_id = ~0;
19746   int ret;
19747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19748     {
19749       if (unformat (input, "if_id %d", &if_id))
19750         ;
19751       else
19752         break;
19753     }
19754   if (if_id == ~0)
19755     {
19756       errmsg ("missing pg interface index");
19757       return -99;
19758     }
19759
19760   /* Construct the API message */
19761   M (PG_CREATE_INTERFACE, mp);
19762   mp->context = 0;
19763   mp->interface_id = ntohl (if_id);
19764
19765   S (mp);
19766   W (ret);
19767   return ret;
19768 }
19769
19770 int
19771 api_pg_capture (vat_main_t * vam)
19772 {
19773   unformat_input_t *input = vam->input;
19774   vl_api_pg_capture_t *mp;
19775
19776   u32 if_id = ~0;
19777   u8 enable = 1;
19778   u32 count = 1;
19779   u8 pcap_file_set = 0;
19780   u8 *pcap_file = 0;
19781   int ret;
19782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19783     {
19784       if (unformat (input, "if_id %d", &if_id))
19785         ;
19786       else if (unformat (input, "pcap %s", &pcap_file))
19787         pcap_file_set = 1;
19788       else if (unformat (input, "count %d", &count))
19789         ;
19790       else if (unformat (input, "disable"))
19791         enable = 0;
19792       else
19793         break;
19794     }
19795   if (if_id == ~0)
19796     {
19797       errmsg ("missing pg interface index");
19798       return -99;
19799     }
19800   if (pcap_file_set > 0)
19801     {
19802       if (vec_len (pcap_file) > 255)
19803         {
19804           errmsg ("pcap file name is too long");
19805           return -99;
19806         }
19807     }
19808
19809   u32 name_len = vec_len (pcap_file);
19810   /* Construct the API message */
19811   M (PG_CAPTURE, mp);
19812   mp->context = 0;
19813   mp->interface_id = ntohl (if_id);
19814   mp->is_enabled = enable;
19815   mp->count = ntohl (count);
19816   mp->pcap_name_length = ntohl (name_len);
19817   if (pcap_file_set != 0)
19818     {
19819       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19820     }
19821   vec_free (pcap_file);
19822
19823   S (mp);
19824   W (ret);
19825   return ret;
19826 }
19827
19828 int
19829 api_pg_enable_disable (vat_main_t * vam)
19830 {
19831   unformat_input_t *input = vam->input;
19832   vl_api_pg_enable_disable_t *mp;
19833
19834   u8 enable = 1;
19835   u8 stream_name_set = 0;
19836   u8 *stream_name = 0;
19837   int ret;
19838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19839     {
19840       if (unformat (input, "stream %s", &stream_name))
19841         stream_name_set = 1;
19842       else if (unformat (input, "disable"))
19843         enable = 0;
19844       else
19845         break;
19846     }
19847
19848   if (stream_name_set > 0)
19849     {
19850       if (vec_len (stream_name) > 255)
19851         {
19852           errmsg ("stream name too long");
19853           return -99;
19854         }
19855     }
19856
19857   u32 name_len = vec_len (stream_name);
19858   /* Construct the API message */
19859   M (PG_ENABLE_DISABLE, mp);
19860   mp->context = 0;
19861   mp->is_enabled = enable;
19862   if (stream_name_set != 0)
19863     {
19864       mp->stream_name_length = ntohl (name_len);
19865       clib_memcpy (mp->stream_name, stream_name, name_len);
19866     }
19867   vec_free (stream_name);
19868
19869   S (mp);
19870   W (ret);
19871   return ret;
19872 }
19873
19874 int
19875 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19876 {
19877   unformat_input_t *input = vam->input;
19878   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19879
19880   u16 *low_ports = 0;
19881   u16 *high_ports = 0;
19882   u16 this_low;
19883   u16 this_hi;
19884   vl_api_prefix_t prefix;
19885   u32 tmp, tmp2;
19886   u8 prefix_set = 0;
19887   u32 vrf_id = ~0;
19888   u8 is_add = 1;
19889   int ret;
19890
19891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19892     {
19893       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19894         prefix_set = 1;
19895       else if (unformat (input, "vrf %d", &vrf_id))
19896         ;
19897       else if (unformat (input, "del"))
19898         is_add = 0;
19899       else if (unformat (input, "port %d", &tmp))
19900         {
19901           if (tmp == 0 || tmp > 65535)
19902             {
19903               errmsg ("port %d out of range", tmp);
19904               return -99;
19905             }
19906           this_low = tmp;
19907           this_hi = this_low + 1;
19908           vec_add1 (low_ports, this_low);
19909           vec_add1 (high_ports, this_hi);
19910         }
19911       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19912         {
19913           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19914             {
19915               errmsg ("incorrect range parameters");
19916               return -99;
19917             }
19918           this_low = tmp;
19919           /* Note: in debug CLI +1 is added to high before
19920              passing to real fn that does "the work"
19921              (ip_source_and_port_range_check_add_del).
19922              This fn is a wrapper around the binary API fn a
19923              control plane will call, which expects this increment
19924              to have occurred. Hence letting the binary API control
19925              plane fn do the increment for consistency between VAT
19926              and other control planes.
19927            */
19928           this_hi = tmp2;
19929           vec_add1 (low_ports, this_low);
19930           vec_add1 (high_ports, this_hi);
19931         }
19932       else
19933         break;
19934     }
19935
19936   if (prefix_set == 0)
19937     {
19938       errmsg ("<address>/<mask> not specified");
19939       return -99;
19940     }
19941
19942   if (vrf_id == ~0)
19943     {
19944       errmsg ("VRF ID required, not specified");
19945       return -99;
19946     }
19947
19948   if (vrf_id == 0)
19949     {
19950       errmsg
19951         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19952       return -99;
19953     }
19954
19955   if (vec_len (low_ports) == 0)
19956     {
19957       errmsg ("At least one port or port range required");
19958       return -99;
19959     }
19960
19961   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19962
19963   mp->is_add = is_add;
19964
19965   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19966
19967   mp->number_of_ranges = vec_len (low_ports);
19968
19969   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19970   vec_free (low_ports);
19971
19972   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19973   vec_free (high_ports);
19974
19975   mp->vrf_id = ntohl (vrf_id);
19976
19977   S (mp);
19978   W (ret);
19979   return ret;
19980 }
19981
19982 int
19983 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19984 {
19985   unformat_input_t *input = vam->input;
19986   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19987   u32 sw_if_index = ~0;
19988   int vrf_set = 0;
19989   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19990   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19991   u8 is_add = 1;
19992   int ret;
19993
19994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19995     {
19996       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19997         ;
19998       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19999         ;
20000       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20001         vrf_set = 1;
20002       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20003         vrf_set = 1;
20004       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20005         vrf_set = 1;
20006       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20007         vrf_set = 1;
20008       else if (unformat (input, "del"))
20009         is_add = 0;
20010       else
20011         break;
20012     }
20013
20014   if (sw_if_index == ~0)
20015     {
20016       errmsg ("Interface required but not specified");
20017       return -99;
20018     }
20019
20020   if (vrf_set == 0)
20021     {
20022       errmsg ("VRF ID required but not specified");
20023       return -99;
20024     }
20025
20026   if (tcp_out_vrf_id == 0
20027       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20028     {
20029       errmsg
20030         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20031       return -99;
20032     }
20033
20034   /* Construct the API message */
20035   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20036
20037   mp->sw_if_index = ntohl (sw_if_index);
20038   mp->is_add = is_add;
20039   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20040   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20041   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20042   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20043
20044   /* send it... */
20045   S (mp);
20046
20047   /* Wait for a reply... */
20048   W (ret);
20049   return ret;
20050 }
20051
20052 static int
20053 api_set_punt (vat_main_t * vam)
20054 {
20055   unformat_input_t *i = vam->input;
20056   vl_api_address_family_t af;
20057   vl_api_set_punt_t *mp;
20058   u32 protocol = ~0;
20059   u32 port = ~0;
20060   int is_add = 1;
20061   int ret;
20062
20063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20064     {
20065       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20066         ;
20067       else if (unformat (i, "protocol %d", &protocol))
20068         ;
20069       else if (unformat (i, "port %d", &port))
20070         ;
20071       else if (unformat (i, "del"))
20072         is_add = 0;
20073       else
20074         {
20075           clib_warning ("parse error '%U'", format_unformat_error, i);
20076           return -99;
20077         }
20078     }
20079
20080   M (SET_PUNT, mp);
20081
20082   mp->is_add = (u8) is_add;
20083   mp->punt.type = PUNT_API_TYPE_L4;
20084   mp->punt.punt.l4.af = af;
20085   mp->punt.punt.l4.protocol = (u8) protocol;
20086   mp->punt.punt.l4.port = htons ((u16) port);
20087
20088   S (mp);
20089   W (ret);
20090   return ret;
20091 }
20092
20093 static int
20094 api_delete_subif (vat_main_t * vam)
20095 {
20096   unformat_input_t *i = vam->input;
20097   vl_api_delete_subif_t *mp;
20098   u32 sw_if_index = ~0;
20099   int ret;
20100
20101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20102     {
20103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20104         ;
20105       if (unformat (i, "sw_if_index %d", &sw_if_index))
20106         ;
20107       else
20108         break;
20109     }
20110
20111   if (sw_if_index == ~0)
20112     {
20113       errmsg ("missing sw_if_index");
20114       return -99;
20115     }
20116
20117   /* Construct the API message */
20118   M (DELETE_SUBIF, mp);
20119   mp->sw_if_index = ntohl (sw_if_index);
20120
20121   S (mp);
20122   W (ret);
20123   return ret;
20124 }
20125
20126 #define foreach_pbb_vtr_op      \
20127 _("disable",  L2_VTR_DISABLED)  \
20128 _("pop",  L2_VTR_POP_2)         \
20129 _("push",  L2_VTR_PUSH_2)
20130
20131 static int
20132 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20133 {
20134   unformat_input_t *i = vam->input;
20135   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20136   u32 sw_if_index = ~0, vtr_op = ~0;
20137   u16 outer_tag = ~0;
20138   u8 dmac[6], smac[6];
20139   u8 dmac_set = 0, smac_set = 0;
20140   u16 vlanid = 0;
20141   u32 sid = ~0;
20142   u32 tmp;
20143   int ret;
20144
20145   /* Shut up coverity */
20146   clib_memset (dmac, 0, sizeof (dmac));
20147   clib_memset (smac, 0, sizeof (smac));
20148
20149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20150     {
20151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20152         ;
20153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20154         ;
20155       else if (unformat (i, "vtr_op %d", &vtr_op))
20156         ;
20157 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20158       foreach_pbb_vtr_op
20159 #undef _
20160         else if (unformat (i, "translate_pbb_stag"))
20161         {
20162           if (unformat (i, "%d", &tmp))
20163             {
20164               vtr_op = L2_VTR_TRANSLATE_2_1;
20165               outer_tag = tmp;
20166             }
20167           else
20168             {
20169               errmsg
20170                 ("translate_pbb_stag operation requires outer tag definition");
20171               return -99;
20172             }
20173         }
20174       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20175         dmac_set++;
20176       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20177         smac_set++;
20178       else if (unformat (i, "sid %d", &sid))
20179         ;
20180       else if (unformat (i, "vlanid %d", &tmp))
20181         vlanid = tmp;
20182       else
20183         {
20184           clib_warning ("parse error '%U'", format_unformat_error, i);
20185           return -99;
20186         }
20187     }
20188
20189   if ((sw_if_index == ~0) || (vtr_op == ~0))
20190     {
20191       errmsg ("missing sw_if_index or vtr operation");
20192       return -99;
20193     }
20194   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20195       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20196     {
20197       errmsg
20198         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20199       return -99;
20200     }
20201
20202   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20203   mp->sw_if_index = ntohl (sw_if_index);
20204   mp->vtr_op = ntohl (vtr_op);
20205   mp->outer_tag = ntohs (outer_tag);
20206   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20207   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20208   mp->b_vlanid = ntohs (vlanid);
20209   mp->i_sid = ntohl (sid);
20210
20211   S (mp);
20212   W (ret);
20213   return ret;
20214 }
20215
20216 static int
20217 api_flow_classify_set_interface (vat_main_t * vam)
20218 {
20219   unformat_input_t *i = vam->input;
20220   vl_api_flow_classify_set_interface_t *mp;
20221   u32 sw_if_index;
20222   int sw_if_index_set;
20223   u32 ip4_table_index = ~0;
20224   u32 ip6_table_index = ~0;
20225   u8 is_add = 1;
20226   int ret;
20227
20228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20229     {
20230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20231         sw_if_index_set = 1;
20232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20233         sw_if_index_set = 1;
20234       else if (unformat (i, "del"))
20235         is_add = 0;
20236       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20237         ;
20238       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20239         ;
20240       else
20241         {
20242           clib_warning ("parse error '%U'", format_unformat_error, i);
20243           return -99;
20244         }
20245     }
20246
20247   if (sw_if_index_set == 0)
20248     {
20249       errmsg ("missing interface name or sw_if_index");
20250       return -99;
20251     }
20252
20253   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20254
20255   mp->sw_if_index = ntohl (sw_if_index);
20256   mp->ip4_table_index = ntohl (ip4_table_index);
20257   mp->ip6_table_index = ntohl (ip6_table_index);
20258   mp->is_add = is_add;
20259
20260   S (mp);
20261   W (ret);
20262   return ret;
20263 }
20264
20265 static int
20266 api_flow_classify_dump (vat_main_t * vam)
20267 {
20268   unformat_input_t *i = vam->input;
20269   vl_api_flow_classify_dump_t *mp;
20270   vl_api_control_ping_t *mp_ping;
20271   u8 type = FLOW_CLASSIFY_N_TABLES;
20272   int ret;
20273
20274   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20275     ;
20276   else
20277     {
20278       errmsg ("classify table type must be specified");
20279       return -99;
20280     }
20281
20282   if (!vam->json_output)
20283     {
20284       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20285     }
20286
20287   M (FLOW_CLASSIFY_DUMP, mp);
20288   mp->type = type;
20289   /* send it... */
20290   S (mp);
20291
20292   /* Use a control ping for synchronization */
20293   MPING (CONTROL_PING, mp_ping);
20294   S (mp_ping);
20295
20296   /* Wait for a reply... */
20297   W (ret);
20298   return ret;
20299 }
20300
20301 static int
20302 api_feature_enable_disable (vat_main_t * vam)
20303 {
20304   unformat_input_t *i = vam->input;
20305   vl_api_feature_enable_disable_t *mp;
20306   u8 *arc_name = 0;
20307   u8 *feature_name = 0;
20308   u32 sw_if_index = ~0;
20309   u8 enable = 1;
20310   int ret;
20311
20312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20313     {
20314       if (unformat (i, "arc_name %s", &arc_name))
20315         ;
20316       else if (unformat (i, "feature_name %s", &feature_name))
20317         ;
20318       else
20319         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20320         ;
20321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20322         ;
20323       else if (unformat (i, "disable"))
20324         enable = 0;
20325       else
20326         break;
20327     }
20328
20329   if (arc_name == 0)
20330     {
20331       errmsg ("missing arc name");
20332       return -99;
20333     }
20334   if (vec_len (arc_name) > 63)
20335     {
20336       errmsg ("arc name too long");
20337     }
20338
20339   if (feature_name == 0)
20340     {
20341       errmsg ("missing feature name");
20342       return -99;
20343     }
20344   if (vec_len (feature_name) > 63)
20345     {
20346       errmsg ("feature name too long");
20347     }
20348
20349   if (sw_if_index == ~0)
20350     {
20351       errmsg ("missing interface name or sw_if_index");
20352       return -99;
20353     }
20354
20355   /* Construct the API message */
20356   M (FEATURE_ENABLE_DISABLE, mp);
20357   mp->sw_if_index = ntohl (sw_if_index);
20358   mp->enable = enable;
20359   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20360   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20361   vec_free (arc_name);
20362   vec_free (feature_name);
20363
20364   S (mp);
20365   W (ret);
20366   return ret;
20367 }
20368
20369 static int
20370 api_sw_interface_tag_add_del (vat_main_t * vam)
20371 {
20372   unformat_input_t *i = vam->input;
20373   vl_api_sw_interface_tag_add_del_t *mp;
20374   u32 sw_if_index = ~0;
20375   u8 *tag = 0;
20376   u8 enable = 1;
20377   int ret;
20378
20379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20380     {
20381       if (unformat (i, "tag %s", &tag))
20382         ;
20383       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20384         ;
20385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20386         ;
20387       else if (unformat (i, "del"))
20388         enable = 0;
20389       else
20390         break;
20391     }
20392
20393   if (sw_if_index == ~0)
20394     {
20395       errmsg ("missing interface name or sw_if_index");
20396       return -99;
20397     }
20398
20399   if (enable && (tag == 0))
20400     {
20401       errmsg ("no tag specified");
20402       return -99;
20403     }
20404
20405   /* Construct the API message */
20406   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20407   mp->sw_if_index = ntohl (sw_if_index);
20408   mp->is_add = enable;
20409   if (enable)
20410     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20411   vec_free (tag);
20412
20413   S (mp);
20414   W (ret);
20415   return ret;
20416 }
20417
20418 static void vl_api_l2_xconnect_details_t_handler
20419   (vl_api_l2_xconnect_details_t * mp)
20420 {
20421   vat_main_t *vam = &vat_main;
20422
20423   print (vam->ofp, "%15d%15d",
20424          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20425 }
20426
20427 static void vl_api_l2_xconnect_details_t_handler_json
20428   (vl_api_l2_xconnect_details_t * mp)
20429 {
20430   vat_main_t *vam = &vat_main;
20431   vat_json_node_t *node = NULL;
20432
20433   if (VAT_JSON_ARRAY != vam->json_tree.type)
20434     {
20435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20436       vat_json_init_array (&vam->json_tree);
20437     }
20438   node = vat_json_array_add (&vam->json_tree);
20439
20440   vat_json_init_object (node);
20441   vat_json_object_add_uint (node, "rx_sw_if_index",
20442                             ntohl (mp->rx_sw_if_index));
20443   vat_json_object_add_uint (node, "tx_sw_if_index",
20444                             ntohl (mp->tx_sw_if_index));
20445 }
20446
20447 static int
20448 api_l2_xconnect_dump (vat_main_t * vam)
20449 {
20450   vl_api_l2_xconnect_dump_t *mp;
20451   vl_api_control_ping_t *mp_ping;
20452   int ret;
20453
20454   if (!vam->json_output)
20455     {
20456       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20457     }
20458
20459   M (L2_XCONNECT_DUMP, mp);
20460
20461   S (mp);
20462
20463   /* Use a control ping for synchronization */
20464   MPING (CONTROL_PING, mp_ping);
20465   S (mp_ping);
20466
20467   W (ret);
20468   return ret;
20469 }
20470
20471 static int
20472 api_hw_interface_set_mtu (vat_main_t * vam)
20473 {
20474   unformat_input_t *i = vam->input;
20475   vl_api_hw_interface_set_mtu_t *mp;
20476   u32 sw_if_index = ~0;
20477   u32 mtu = 0;
20478   int ret;
20479
20480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20481     {
20482       if (unformat (i, "mtu %d", &mtu))
20483         ;
20484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20485         ;
20486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20487         ;
20488       else
20489         break;
20490     }
20491
20492   if (sw_if_index == ~0)
20493     {
20494       errmsg ("missing interface name or sw_if_index");
20495       return -99;
20496     }
20497
20498   if (mtu == 0)
20499     {
20500       errmsg ("no mtu specified");
20501       return -99;
20502     }
20503
20504   /* Construct the API message */
20505   M (HW_INTERFACE_SET_MTU, mp);
20506   mp->sw_if_index = ntohl (sw_if_index);
20507   mp->mtu = ntohs ((u16) mtu);
20508
20509   S (mp);
20510   W (ret);
20511   return ret;
20512 }
20513
20514 static int
20515 api_p2p_ethernet_add (vat_main_t * vam)
20516 {
20517   unformat_input_t *i = vam->input;
20518   vl_api_p2p_ethernet_add_t *mp;
20519   u32 parent_if_index = ~0;
20520   u32 sub_id = ~0;
20521   u8 remote_mac[6];
20522   u8 mac_set = 0;
20523   int ret;
20524
20525   clib_memset (remote_mac, 0, sizeof (remote_mac));
20526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20527     {
20528       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20529         ;
20530       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20531         ;
20532       else
20533         if (unformat
20534             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20535         mac_set++;
20536       else if (unformat (i, "sub_id %d", &sub_id))
20537         ;
20538       else
20539         {
20540           clib_warning ("parse error '%U'", format_unformat_error, i);
20541           return -99;
20542         }
20543     }
20544
20545   if (parent_if_index == ~0)
20546     {
20547       errmsg ("missing interface name or sw_if_index");
20548       return -99;
20549     }
20550   if (mac_set == 0)
20551     {
20552       errmsg ("missing remote mac address");
20553       return -99;
20554     }
20555   if (sub_id == ~0)
20556     {
20557       errmsg ("missing sub-interface id");
20558       return -99;
20559     }
20560
20561   M (P2P_ETHERNET_ADD, mp);
20562   mp->parent_if_index = ntohl (parent_if_index);
20563   mp->subif_id = ntohl (sub_id);
20564   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20565
20566   S (mp);
20567   W (ret);
20568   return ret;
20569 }
20570
20571 static int
20572 api_p2p_ethernet_del (vat_main_t * vam)
20573 {
20574   unformat_input_t *i = vam->input;
20575   vl_api_p2p_ethernet_del_t *mp;
20576   u32 parent_if_index = ~0;
20577   u8 remote_mac[6];
20578   u8 mac_set = 0;
20579   int ret;
20580
20581   clib_memset (remote_mac, 0, sizeof (remote_mac));
20582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20583     {
20584       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20585         ;
20586       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20587         ;
20588       else
20589         if (unformat
20590             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20591         mac_set++;
20592       else
20593         {
20594           clib_warning ("parse error '%U'", format_unformat_error, i);
20595           return -99;
20596         }
20597     }
20598
20599   if (parent_if_index == ~0)
20600     {
20601       errmsg ("missing interface name or sw_if_index");
20602       return -99;
20603     }
20604   if (mac_set == 0)
20605     {
20606       errmsg ("missing remote mac address");
20607       return -99;
20608     }
20609
20610   M (P2P_ETHERNET_DEL, mp);
20611   mp->parent_if_index = ntohl (parent_if_index);
20612   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20613
20614   S (mp);
20615   W (ret);
20616   return ret;
20617 }
20618
20619 static int
20620 api_lldp_config (vat_main_t * vam)
20621 {
20622   unformat_input_t *i = vam->input;
20623   vl_api_lldp_config_t *mp;
20624   int tx_hold = 0;
20625   int tx_interval = 0;
20626   u8 *sys_name = NULL;
20627   int ret;
20628
20629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20630     {
20631       if (unformat (i, "system-name %s", &sys_name))
20632         ;
20633       else if (unformat (i, "tx-hold %d", &tx_hold))
20634         ;
20635       else if (unformat (i, "tx-interval %d", &tx_interval))
20636         ;
20637       else
20638         {
20639           clib_warning ("parse error '%U'", format_unformat_error, i);
20640           return -99;
20641         }
20642     }
20643
20644   vec_add1 (sys_name, 0);
20645
20646   M (LLDP_CONFIG, mp);
20647   mp->tx_hold = htonl (tx_hold);
20648   mp->tx_interval = htonl (tx_interval);
20649   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20650   vec_free (sys_name);
20651
20652   S (mp);
20653   W (ret);
20654   return ret;
20655 }
20656
20657 static int
20658 api_sw_interface_set_lldp (vat_main_t * vam)
20659 {
20660   unformat_input_t *i = vam->input;
20661   vl_api_sw_interface_set_lldp_t *mp;
20662   u32 sw_if_index = ~0;
20663   u32 enable = 1;
20664   u8 *port_desc = NULL, *mgmt_oid = NULL;
20665   ip4_address_t ip4_addr;
20666   ip6_address_t ip6_addr;
20667   int ret;
20668
20669   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20670   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20671
20672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20673     {
20674       if (unformat (i, "disable"))
20675         enable = 0;
20676       else
20677         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20678         ;
20679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20680         ;
20681       else if (unformat (i, "port-desc %s", &port_desc))
20682         ;
20683       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20684         ;
20685       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20686         ;
20687       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20688         ;
20689       else
20690         break;
20691     }
20692
20693   if (sw_if_index == ~0)
20694     {
20695       errmsg ("missing interface name or sw_if_index");
20696       return -99;
20697     }
20698
20699   /* Construct the API message */
20700   vec_add1 (port_desc, 0);
20701   vec_add1 (mgmt_oid, 0);
20702   M (SW_INTERFACE_SET_LLDP, mp);
20703   mp->sw_if_index = ntohl (sw_if_index);
20704   mp->enable = enable;
20705   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20706   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20707   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20708   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20709   vec_free (port_desc);
20710   vec_free (mgmt_oid);
20711
20712   S (mp);
20713   W (ret);
20714   return ret;
20715 }
20716
20717 static int
20718 api_tcp_configure_src_addresses (vat_main_t * vam)
20719 {
20720   vl_api_tcp_configure_src_addresses_t *mp;
20721   unformat_input_t *i = vam->input;
20722   ip4_address_t v4first, v4last;
20723   ip6_address_t v6first, v6last;
20724   u8 range_set = 0;
20725   u32 vrf_id = 0;
20726   int ret;
20727
20728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20729     {
20730       if (unformat (i, "%U - %U",
20731                     unformat_ip4_address, &v4first,
20732                     unformat_ip4_address, &v4last))
20733         {
20734           if (range_set)
20735             {
20736               errmsg ("one range per message (range already set)");
20737               return -99;
20738             }
20739           range_set = 1;
20740         }
20741       else if (unformat (i, "%U - %U",
20742                          unformat_ip6_address, &v6first,
20743                          unformat_ip6_address, &v6last))
20744         {
20745           if (range_set)
20746             {
20747               errmsg ("one range per message (range already set)");
20748               return -99;
20749             }
20750           range_set = 2;
20751         }
20752       else if (unformat (i, "vrf %d", &vrf_id))
20753         ;
20754       else
20755         break;
20756     }
20757
20758   if (range_set == 0)
20759     {
20760       errmsg ("address range not set");
20761       return -99;
20762     }
20763
20764   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20765   mp->vrf_id = ntohl (vrf_id);
20766   /* ipv6? */
20767   if (range_set == 2)
20768     {
20769       mp->is_ipv6 = 1;
20770       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20771       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20772     }
20773   else
20774     {
20775       mp->is_ipv6 = 0;
20776       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20777       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20778     }
20779   S (mp);
20780   W (ret);
20781   return ret;
20782 }
20783
20784 static void vl_api_app_namespace_add_del_reply_t_handler
20785   (vl_api_app_namespace_add_del_reply_t * mp)
20786 {
20787   vat_main_t *vam = &vat_main;
20788   i32 retval = ntohl (mp->retval);
20789   if (vam->async_mode)
20790     {
20791       vam->async_errors += (retval < 0);
20792     }
20793   else
20794     {
20795       vam->retval = retval;
20796       if (retval == 0)
20797         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20798       vam->result_ready = 1;
20799     }
20800 }
20801
20802 static void vl_api_app_namespace_add_del_reply_t_handler_json
20803   (vl_api_app_namespace_add_del_reply_t * mp)
20804 {
20805   vat_main_t *vam = &vat_main;
20806   vat_json_node_t node;
20807
20808   vat_json_init_object (&node);
20809   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20810   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20811
20812   vat_json_print (vam->ofp, &node);
20813   vat_json_free (&node);
20814
20815   vam->retval = ntohl (mp->retval);
20816   vam->result_ready = 1;
20817 }
20818
20819 static int
20820 api_app_namespace_add_del (vat_main_t * vam)
20821 {
20822   vl_api_app_namespace_add_del_t *mp;
20823   unformat_input_t *i = vam->input;
20824   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20825   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20826   u64 secret;
20827   int ret;
20828
20829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20830     {
20831       if (unformat (i, "id %_%v%_", &ns_id))
20832         ;
20833       else if (unformat (i, "secret %lu", &secret))
20834         secret_set = 1;
20835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20836         sw_if_index_set = 1;
20837       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20838         ;
20839       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20840         ;
20841       else
20842         break;
20843     }
20844   if (!ns_id || !secret_set || !sw_if_index_set)
20845     {
20846       errmsg ("namespace id, secret and sw_if_index must be set");
20847       return -99;
20848     }
20849   if (vec_len (ns_id) > 64)
20850     {
20851       errmsg ("namespace id too long");
20852       return -99;
20853     }
20854   M (APP_NAMESPACE_ADD_DEL, mp);
20855
20856   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20857   mp->namespace_id_len = vec_len (ns_id);
20858   mp->secret = clib_host_to_net_u64 (secret);
20859   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20860   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20861   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20862   vec_free (ns_id);
20863   S (mp);
20864   W (ret);
20865   return ret;
20866 }
20867
20868 static int
20869 api_sock_init_shm (vat_main_t * vam)
20870 {
20871 #if VPP_API_TEST_BUILTIN == 0
20872   unformat_input_t *i = vam->input;
20873   vl_api_shm_elem_config_t *config = 0;
20874   u64 size = 64 << 20;
20875   int rv;
20876
20877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20878     {
20879       if (unformat (i, "size %U", unformat_memory_size, &size))
20880         ;
20881       else
20882         break;
20883     }
20884
20885   /*
20886    * Canned custom ring allocator config.
20887    * Should probably parse all of this
20888    */
20889   vec_validate (config, 6);
20890   config[0].type = VL_API_VLIB_RING;
20891   config[0].size = 256;
20892   config[0].count = 32;
20893
20894   config[1].type = VL_API_VLIB_RING;
20895   config[1].size = 1024;
20896   config[1].count = 16;
20897
20898   config[2].type = VL_API_VLIB_RING;
20899   config[2].size = 4096;
20900   config[2].count = 2;
20901
20902   config[3].type = VL_API_CLIENT_RING;
20903   config[3].size = 256;
20904   config[3].count = 32;
20905
20906   config[4].type = VL_API_CLIENT_RING;
20907   config[4].size = 1024;
20908   config[4].count = 16;
20909
20910   config[5].type = VL_API_CLIENT_RING;
20911   config[5].size = 4096;
20912   config[5].count = 2;
20913
20914   config[6].type = VL_API_QUEUE;
20915   config[6].count = 128;
20916   config[6].size = sizeof (uword);
20917
20918   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20919   if (!rv)
20920     vam->client_index_invalid = 1;
20921   return rv;
20922 #else
20923   return -99;
20924 #endif
20925 }
20926
20927 static int
20928 api_dns_enable_disable (vat_main_t * vam)
20929 {
20930   unformat_input_t *line_input = vam->input;
20931   vl_api_dns_enable_disable_t *mp;
20932   u8 enable_disable = 1;
20933   int ret;
20934
20935   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20936     {
20937       if (unformat (line_input, "disable"))
20938         enable_disable = 0;
20939       if (unformat (line_input, "enable"))
20940         enable_disable = 1;
20941       else
20942         break;
20943     }
20944
20945   /* Construct the API message */
20946   M (DNS_ENABLE_DISABLE, mp);
20947   mp->enable = enable_disable;
20948
20949   /* send it... */
20950   S (mp);
20951   /* Wait for the reply */
20952   W (ret);
20953   return ret;
20954 }
20955
20956 static int
20957 api_dns_resolve_name (vat_main_t * vam)
20958 {
20959   unformat_input_t *line_input = vam->input;
20960   vl_api_dns_resolve_name_t *mp;
20961   u8 *name = 0;
20962   int ret;
20963
20964   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20965     {
20966       if (unformat (line_input, "%s", &name))
20967         ;
20968       else
20969         break;
20970     }
20971
20972   if (vec_len (name) > 127)
20973     {
20974       errmsg ("name too long");
20975       return -99;
20976     }
20977
20978   /* Construct the API message */
20979   M (DNS_RESOLVE_NAME, mp);
20980   memcpy (mp->name, name, vec_len (name));
20981   vec_free (name);
20982
20983   /* send it... */
20984   S (mp);
20985   /* Wait for the reply */
20986   W (ret);
20987   return ret;
20988 }
20989
20990 static int
20991 api_dns_resolve_ip (vat_main_t * vam)
20992 {
20993   unformat_input_t *line_input = vam->input;
20994   vl_api_dns_resolve_ip_t *mp;
20995   int is_ip6 = -1;
20996   ip4_address_t addr4;
20997   ip6_address_t addr6;
20998   int ret;
20999
21000   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21001     {
21002       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21003         is_ip6 = 1;
21004       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21005         is_ip6 = 0;
21006       else
21007         break;
21008     }
21009
21010   if (is_ip6 == -1)
21011     {
21012       errmsg ("missing address");
21013       return -99;
21014     }
21015
21016   /* Construct the API message */
21017   M (DNS_RESOLVE_IP, mp);
21018   mp->is_ip6 = is_ip6;
21019   if (is_ip6)
21020     memcpy (mp->address, &addr6, sizeof (addr6));
21021   else
21022     memcpy (mp->address, &addr4, sizeof (addr4));
21023
21024   /* send it... */
21025   S (mp);
21026   /* Wait for the reply */
21027   W (ret);
21028   return ret;
21029 }
21030
21031 static int
21032 api_dns_name_server_add_del (vat_main_t * vam)
21033 {
21034   unformat_input_t *i = vam->input;
21035   vl_api_dns_name_server_add_del_t *mp;
21036   u8 is_add = 1;
21037   ip6_address_t ip6_server;
21038   ip4_address_t ip4_server;
21039   int ip6_set = 0;
21040   int ip4_set = 0;
21041   int ret = 0;
21042
21043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21044     {
21045       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21046         ip6_set = 1;
21047       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21048         ip4_set = 1;
21049       else if (unformat (i, "del"))
21050         is_add = 0;
21051       else
21052         {
21053           clib_warning ("parse error '%U'", format_unformat_error, i);
21054           return -99;
21055         }
21056     }
21057
21058   if (ip4_set && ip6_set)
21059     {
21060       errmsg ("Only one server address allowed per message");
21061       return -99;
21062     }
21063   if ((ip4_set + ip6_set) == 0)
21064     {
21065       errmsg ("Server address required");
21066       return -99;
21067     }
21068
21069   /* Construct the API message */
21070   M (DNS_NAME_SERVER_ADD_DEL, mp);
21071
21072   if (ip6_set)
21073     {
21074       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21075       mp->is_ip6 = 1;
21076     }
21077   else
21078     {
21079       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21080       mp->is_ip6 = 0;
21081     }
21082
21083   mp->is_add = is_add;
21084
21085   /* send it... */
21086   S (mp);
21087
21088   /* Wait for a reply, return good/bad news  */
21089   W (ret);
21090   return ret;
21091 }
21092
21093 static void
21094 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21095 {
21096   vat_main_t *vam = &vat_main;
21097
21098   if (mp->is_ip4)
21099     {
21100       print (vam->ofp,
21101              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21102              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21103              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21104              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21105              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21106              clib_net_to_host_u32 (mp->action_index), mp->tag);
21107     }
21108   else
21109     {
21110       print (vam->ofp,
21111              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21112              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21113              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21114              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21115              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21116              clib_net_to_host_u32 (mp->action_index), mp->tag);
21117     }
21118 }
21119
21120 static void
21121 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21122                                              mp)
21123 {
21124   vat_main_t *vam = &vat_main;
21125   vat_json_node_t *node = NULL;
21126   struct in6_addr ip6;
21127   struct in_addr ip4;
21128
21129   if (VAT_JSON_ARRAY != vam->json_tree.type)
21130     {
21131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21132       vat_json_init_array (&vam->json_tree);
21133     }
21134   node = vat_json_array_add (&vam->json_tree);
21135   vat_json_init_object (node);
21136
21137   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21138   vat_json_object_add_uint (node, "appns_index",
21139                             clib_net_to_host_u32 (mp->appns_index));
21140   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21141   vat_json_object_add_uint (node, "scope", mp->scope);
21142   vat_json_object_add_uint (node, "action_index",
21143                             clib_net_to_host_u32 (mp->action_index));
21144   vat_json_object_add_uint (node, "lcl_port",
21145                             clib_net_to_host_u16 (mp->lcl_port));
21146   vat_json_object_add_uint (node, "rmt_port",
21147                             clib_net_to_host_u16 (mp->rmt_port));
21148   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21149   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21150   vat_json_object_add_string_copy (node, "tag", mp->tag);
21151   if (mp->is_ip4)
21152     {
21153       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21154       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21155       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21156       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21157     }
21158   else
21159     {
21160       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21161       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21162       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21163       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21164     }
21165 }
21166
21167 static int
21168 api_session_rule_add_del (vat_main_t * vam)
21169 {
21170   vl_api_session_rule_add_del_t *mp;
21171   unformat_input_t *i = vam->input;
21172   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21173   u32 appns_index = 0, scope = 0;
21174   ip4_address_t lcl_ip4, rmt_ip4;
21175   ip6_address_t lcl_ip6, rmt_ip6;
21176   u8 is_ip4 = 1, conn_set = 0;
21177   u8 is_add = 1, *tag = 0;
21178   int ret;
21179
21180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21181     {
21182       if (unformat (i, "del"))
21183         is_add = 0;
21184       else if (unformat (i, "add"))
21185         ;
21186       else if (unformat (i, "proto tcp"))
21187         proto = 0;
21188       else if (unformat (i, "proto udp"))
21189         proto = 1;
21190       else if (unformat (i, "appns %d", &appns_index))
21191         ;
21192       else if (unformat (i, "scope %d", &scope))
21193         ;
21194       else if (unformat (i, "tag %_%v%_", &tag))
21195         ;
21196       else
21197         if (unformat
21198             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21199              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21200              &rmt_port))
21201         {
21202           is_ip4 = 1;
21203           conn_set = 1;
21204         }
21205       else
21206         if (unformat
21207             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21208              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21209              &rmt_port))
21210         {
21211           is_ip4 = 0;
21212           conn_set = 1;
21213         }
21214       else if (unformat (i, "action %d", &action))
21215         ;
21216       else
21217         break;
21218     }
21219   if (proto == ~0 || !conn_set || action == ~0)
21220     {
21221       errmsg ("transport proto, connection and action must be set");
21222       return -99;
21223     }
21224
21225   if (scope > 3)
21226     {
21227       errmsg ("scope should be 0-3");
21228       return -99;
21229     }
21230
21231   M (SESSION_RULE_ADD_DEL, mp);
21232
21233   mp->is_ip4 = is_ip4;
21234   mp->transport_proto = proto;
21235   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21236   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21237   mp->lcl_plen = lcl_plen;
21238   mp->rmt_plen = rmt_plen;
21239   mp->action_index = clib_host_to_net_u32 (action);
21240   mp->appns_index = clib_host_to_net_u32 (appns_index);
21241   mp->scope = scope;
21242   mp->is_add = is_add;
21243   if (is_ip4)
21244     {
21245       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21246       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21247     }
21248   else
21249     {
21250       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21251       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21252     }
21253   if (tag)
21254     {
21255       clib_memcpy (mp->tag, tag, vec_len (tag));
21256       vec_free (tag);
21257     }
21258
21259   S (mp);
21260   W (ret);
21261   return ret;
21262 }
21263
21264 static int
21265 api_session_rules_dump (vat_main_t * vam)
21266 {
21267   vl_api_session_rules_dump_t *mp;
21268   vl_api_control_ping_t *mp_ping;
21269   int ret;
21270
21271   if (!vam->json_output)
21272     {
21273       print (vam->ofp, "%=20s", "Session Rules");
21274     }
21275
21276   M (SESSION_RULES_DUMP, mp);
21277   /* send it... */
21278   S (mp);
21279
21280   /* Use a control ping for synchronization */
21281   MPING (CONTROL_PING, mp_ping);
21282   S (mp_ping);
21283
21284   /* Wait for a reply... */
21285   W (ret);
21286   return ret;
21287 }
21288
21289 static int
21290 api_ip_container_proxy_add_del (vat_main_t * vam)
21291 {
21292   vl_api_ip_container_proxy_add_del_t *mp;
21293   unformat_input_t *i = vam->input;
21294   u32 sw_if_index = ~0;
21295   vl_api_prefix_t pfx = { };
21296   u8 is_add = 1;
21297   int ret;
21298
21299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21300     {
21301       if (unformat (i, "del"))
21302         is_add = 0;
21303       else if (unformat (i, "add"))
21304         ;
21305       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21306         ;
21307       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21308         ;
21309       else
21310         break;
21311     }
21312   if (sw_if_index == ~0 || pfx.address_length == 0)
21313     {
21314       errmsg ("address and sw_if_index must be set");
21315       return -99;
21316     }
21317
21318   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21319
21320   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21321   mp->is_add = is_add;
21322   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21323
21324   S (mp);
21325   W (ret);
21326   return ret;
21327 }
21328
21329 static int
21330 api_qos_record_enable_disable (vat_main_t * vam)
21331 {
21332   unformat_input_t *i = vam->input;
21333   vl_api_qos_record_enable_disable_t *mp;
21334   u32 sw_if_index, qs = 0xff;
21335   u8 sw_if_index_set = 0;
21336   u8 enable = 1;
21337   int ret;
21338
21339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21340     {
21341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21342         sw_if_index_set = 1;
21343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21344         sw_if_index_set = 1;
21345       else if (unformat (i, "%U", unformat_qos_source, &qs))
21346         ;
21347       else if (unformat (i, "disable"))
21348         enable = 0;
21349       else
21350         {
21351           clib_warning ("parse error '%U'", format_unformat_error, i);
21352           return -99;
21353         }
21354     }
21355
21356   if (sw_if_index_set == 0)
21357     {
21358       errmsg ("missing interface name or sw_if_index");
21359       return -99;
21360     }
21361   if (qs == 0xff)
21362     {
21363       errmsg ("input location must be specified");
21364       return -99;
21365     }
21366
21367   M (QOS_RECORD_ENABLE_DISABLE, mp);
21368
21369   mp->sw_if_index = ntohl (sw_if_index);
21370   mp->input_source = qs;
21371   mp->enable = enable;
21372
21373   S (mp);
21374   W (ret);
21375   return ret;
21376 }
21377
21378
21379 static int
21380 q_or_quit (vat_main_t * vam)
21381 {
21382 #if VPP_API_TEST_BUILTIN == 0
21383   longjmp (vam->jump_buf, 1);
21384 #endif
21385   return 0;                     /* not so much */
21386 }
21387
21388 static int
21389 q (vat_main_t * vam)
21390 {
21391   return q_or_quit (vam);
21392 }
21393
21394 static int
21395 quit (vat_main_t * vam)
21396 {
21397   return q_or_quit (vam);
21398 }
21399
21400 static int
21401 comment (vat_main_t * vam)
21402 {
21403   return 0;
21404 }
21405
21406 static int
21407 statseg (vat_main_t * vam)
21408 {
21409   ssvm_private_t *ssvmp = &vam->stat_segment;
21410   ssvm_shared_header_t *shared_header = ssvmp->sh;
21411   vlib_counter_t **counters;
21412   u64 thread0_index1_packets;
21413   u64 thread0_index1_bytes;
21414   f64 vector_rate, input_rate;
21415   uword *p;
21416
21417   uword *counter_vector_by_name;
21418   if (vam->stat_segment_lockp == 0)
21419     {
21420       errmsg ("Stat segment not mapped...");
21421       return -99;
21422     }
21423
21424   /* look up "/if/rx for sw_if_index 1 as a test */
21425
21426   clib_spinlock_lock (vam->stat_segment_lockp);
21427
21428   counter_vector_by_name = (uword *) shared_header->opaque[1];
21429
21430   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21431   if (p == 0)
21432     {
21433       clib_spinlock_unlock (vam->stat_segment_lockp);
21434       errmsg ("/if/tx not found?");
21435       return -99;
21436     }
21437
21438   /* Fish per-thread vector of combined counters from shared memory */
21439   counters = (vlib_counter_t **) p[0];
21440
21441   if (vec_len (counters[0]) < 2)
21442     {
21443       clib_spinlock_unlock (vam->stat_segment_lockp);
21444       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21445       return -99;
21446     }
21447
21448   /* Read thread 0 sw_if_index 1 counter */
21449   thread0_index1_packets = counters[0][1].packets;
21450   thread0_index1_bytes = counters[0][1].bytes;
21451
21452   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21453   if (p == 0)
21454     {
21455       clib_spinlock_unlock (vam->stat_segment_lockp);
21456       errmsg ("vector_rate not found?");
21457       return -99;
21458     }
21459
21460   vector_rate = *(f64 *) (p[0]);
21461   p = hash_get_mem (counter_vector_by_name, "input_rate");
21462   if (p == 0)
21463     {
21464       clib_spinlock_unlock (vam->stat_segment_lockp);
21465       errmsg ("input_rate not found?");
21466       return -99;
21467     }
21468   input_rate = *(f64 *) (p[0]);
21469
21470   clib_spinlock_unlock (vam->stat_segment_lockp);
21471
21472   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21473          vector_rate, input_rate);
21474   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21475          thread0_index1_packets, thread0_index1_bytes);
21476
21477   return 0;
21478 }
21479
21480 static int
21481 cmd_cmp (void *a1, void *a2)
21482 {
21483   u8 **c1 = a1;
21484   u8 **c2 = a2;
21485
21486   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21487 }
21488
21489 static int
21490 help (vat_main_t * vam)
21491 {
21492   u8 **cmds = 0;
21493   u8 *name = 0;
21494   hash_pair_t *p;
21495   unformat_input_t *i = vam->input;
21496   int j;
21497
21498   if (unformat (i, "%s", &name))
21499     {
21500       uword *hs;
21501
21502       vec_add1 (name, 0);
21503
21504       hs = hash_get_mem (vam->help_by_name, name);
21505       if (hs)
21506         print (vam->ofp, "usage: %s %s", name, hs[0]);
21507       else
21508         print (vam->ofp, "No such msg / command '%s'", name);
21509       vec_free (name);
21510       return 0;
21511     }
21512
21513   print (vam->ofp, "Help is available for the following:");
21514
21515     /* *INDENT-OFF* */
21516     hash_foreach_pair (p, vam->function_by_name,
21517     ({
21518       vec_add1 (cmds, (u8 *)(p->key));
21519     }));
21520     /* *INDENT-ON* */
21521
21522   vec_sort_with_function (cmds, cmd_cmp);
21523
21524   for (j = 0; j < vec_len (cmds); j++)
21525     print (vam->ofp, "%s", cmds[j]);
21526
21527   vec_free (cmds);
21528   return 0;
21529 }
21530
21531 static int
21532 set (vat_main_t * vam)
21533 {
21534   u8 *name = 0, *value = 0;
21535   unformat_input_t *i = vam->input;
21536
21537   if (unformat (i, "%s", &name))
21538     {
21539       /* The input buffer is a vector, not a string. */
21540       value = vec_dup (i->buffer);
21541       vec_delete (value, i->index, 0);
21542       /* Almost certainly has a trailing newline */
21543       if (value[vec_len (value) - 1] == '\n')
21544         value[vec_len (value) - 1] = 0;
21545       /* Make sure it's a proper string, one way or the other */
21546       vec_add1 (value, 0);
21547       (void) clib_macro_set_value (&vam->macro_main,
21548                                    (char *) name, (char *) value);
21549     }
21550   else
21551     errmsg ("usage: set <name> <value>");
21552
21553   vec_free (name);
21554   vec_free (value);
21555   return 0;
21556 }
21557
21558 static int
21559 unset (vat_main_t * vam)
21560 {
21561   u8 *name = 0;
21562
21563   if (unformat (vam->input, "%s", &name))
21564     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21565       errmsg ("unset: %s wasn't set", name);
21566   vec_free (name);
21567   return 0;
21568 }
21569
21570 typedef struct
21571 {
21572   u8 *name;
21573   u8 *value;
21574 } macro_sort_t;
21575
21576
21577 static int
21578 macro_sort_cmp (void *a1, void *a2)
21579 {
21580   macro_sort_t *s1 = a1;
21581   macro_sort_t *s2 = a2;
21582
21583   return strcmp ((char *) (s1->name), (char *) (s2->name));
21584 }
21585
21586 static int
21587 dump_macro_table (vat_main_t * vam)
21588 {
21589   macro_sort_t *sort_me = 0, *sm;
21590   int i;
21591   hash_pair_t *p;
21592
21593     /* *INDENT-OFF* */
21594     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21595     ({
21596       vec_add2 (sort_me, sm, 1);
21597       sm->name = (u8 *)(p->key);
21598       sm->value = (u8 *) (p->value[0]);
21599     }));
21600     /* *INDENT-ON* */
21601
21602   vec_sort_with_function (sort_me, macro_sort_cmp);
21603
21604   if (vec_len (sort_me))
21605     print (vam->ofp, "%-15s%s", "Name", "Value");
21606   else
21607     print (vam->ofp, "The macro table is empty...");
21608
21609   for (i = 0; i < vec_len (sort_me); i++)
21610     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21611   return 0;
21612 }
21613
21614 static int
21615 dump_node_table (vat_main_t * vam)
21616 {
21617   int i, j;
21618   vlib_node_t *node, *next_node;
21619
21620   if (vec_len (vam->graph_nodes) == 0)
21621     {
21622       print (vam->ofp, "Node table empty, issue get_node_graph...");
21623       return 0;
21624     }
21625
21626   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21627     {
21628       node = vam->graph_nodes[0][i];
21629       print (vam->ofp, "[%d] %s", i, node->name);
21630       for (j = 0; j < vec_len (node->next_nodes); j++)
21631         {
21632           if (node->next_nodes[j] != ~0)
21633             {
21634               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21635               print (vam->ofp, "  [%d] %s", j, next_node->name);
21636             }
21637         }
21638     }
21639   return 0;
21640 }
21641
21642 static int
21643 value_sort_cmp (void *a1, void *a2)
21644 {
21645   name_sort_t *n1 = a1;
21646   name_sort_t *n2 = a2;
21647
21648   if (n1->value < n2->value)
21649     return -1;
21650   if (n1->value > n2->value)
21651     return 1;
21652   return 0;
21653 }
21654
21655
21656 static int
21657 dump_msg_api_table (vat_main_t * vam)
21658 {
21659   api_main_t *am = &api_main;
21660   name_sort_t *nses = 0, *ns;
21661   hash_pair_t *hp;
21662   int i;
21663
21664   /* *INDENT-OFF* */
21665   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21666   ({
21667     vec_add2 (nses, ns, 1);
21668     ns->name = (u8 *)(hp->key);
21669     ns->value = (u32) hp->value[0];
21670   }));
21671   /* *INDENT-ON* */
21672
21673   vec_sort_with_function (nses, value_sort_cmp);
21674
21675   for (i = 0; i < vec_len (nses); i++)
21676     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21677   vec_free (nses);
21678   return 0;
21679 }
21680
21681 static int
21682 get_msg_id (vat_main_t * vam)
21683 {
21684   u8 *name_and_crc;
21685   u32 message_index;
21686
21687   if (unformat (vam->input, "%s", &name_and_crc))
21688     {
21689       message_index = vl_msg_api_get_msg_index (name_and_crc);
21690       if (message_index == ~0)
21691         {
21692           print (vam->ofp, " '%s' not found", name_and_crc);
21693           return 0;
21694         }
21695       print (vam->ofp, " '%s' has message index %d",
21696              name_and_crc, message_index);
21697       return 0;
21698     }
21699   errmsg ("name_and_crc required...");
21700   return 0;
21701 }
21702
21703 static int
21704 search_node_table (vat_main_t * vam)
21705 {
21706   unformat_input_t *line_input = vam->input;
21707   u8 *node_to_find;
21708   int j;
21709   vlib_node_t *node, *next_node;
21710   uword *p;
21711
21712   if (vam->graph_node_index_by_name == 0)
21713     {
21714       print (vam->ofp, "Node table empty, issue get_node_graph...");
21715       return 0;
21716     }
21717
21718   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21719     {
21720       if (unformat (line_input, "%s", &node_to_find))
21721         {
21722           vec_add1 (node_to_find, 0);
21723           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21724           if (p == 0)
21725             {
21726               print (vam->ofp, "%s not found...", node_to_find);
21727               goto out;
21728             }
21729           node = vam->graph_nodes[0][p[0]];
21730           print (vam->ofp, "[%d] %s", p[0], node->name);
21731           for (j = 0; j < vec_len (node->next_nodes); j++)
21732             {
21733               if (node->next_nodes[j] != ~0)
21734                 {
21735                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21736                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21737                 }
21738             }
21739         }
21740
21741       else
21742         {
21743           clib_warning ("parse error '%U'", format_unformat_error,
21744                         line_input);
21745           return -99;
21746         }
21747
21748     out:
21749       vec_free (node_to_find);
21750
21751     }
21752
21753   return 0;
21754 }
21755
21756
21757 static int
21758 script (vat_main_t * vam)
21759 {
21760 #if (VPP_API_TEST_BUILTIN==0)
21761   u8 *s = 0;
21762   char *save_current_file;
21763   unformat_input_t save_input;
21764   jmp_buf save_jump_buf;
21765   u32 save_line_number;
21766
21767   FILE *new_fp, *save_ifp;
21768
21769   if (unformat (vam->input, "%s", &s))
21770     {
21771       new_fp = fopen ((char *) s, "r");
21772       if (new_fp == 0)
21773         {
21774           errmsg ("Couldn't open script file %s", s);
21775           vec_free (s);
21776           return -99;
21777         }
21778     }
21779   else
21780     {
21781       errmsg ("Missing script name");
21782       return -99;
21783     }
21784
21785   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21786   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21787   save_ifp = vam->ifp;
21788   save_line_number = vam->input_line_number;
21789   save_current_file = (char *) vam->current_file;
21790
21791   vam->input_line_number = 0;
21792   vam->ifp = new_fp;
21793   vam->current_file = s;
21794   do_one_file (vam);
21795
21796   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21797   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21798   vam->ifp = save_ifp;
21799   vam->input_line_number = save_line_number;
21800   vam->current_file = (u8 *) save_current_file;
21801   vec_free (s);
21802
21803   return 0;
21804 #else
21805   clib_warning ("use the exec command...");
21806   return -99;
21807 #endif
21808 }
21809
21810 static int
21811 echo (vat_main_t * vam)
21812 {
21813   print (vam->ofp, "%v", vam->input->buffer);
21814   return 0;
21815 }
21816
21817 /* List of API message constructors, CLI names map to api_xxx */
21818 #define foreach_vpe_api_msg                                             \
21819 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21820 _(sw_interface_dump,"")                                                 \
21821 _(sw_interface_set_flags,                                               \
21822   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21823 _(sw_interface_add_del_address,                                         \
21824   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21825 _(sw_interface_set_rx_mode,                                             \
21826   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21827 _(sw_interface_set_rx_placement,                                        \
21828   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21829 _(sw_interface_rx_placement_dump,                                       \
21830   "[<intfc> | sw_if_index <id>]")                                         \
21831 _(sw_interface_set_table,                                               \
21832   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21833 _(sw_interface_set_mpls_enable,                                         \
21834   "<intfc> | sw_if_index [disable | dis]")                              \
21835 _(sw_interface_set_vpath,                                               \
21836   "<intfc> | sw_if_index <id> enable | disable")                        \
21837 _(sw_interface_set_vxlan_bypass,                                        \
21838   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21839 _(sw_interface_set_geneve_bypass,                                       \
21840   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21841 _(sw_interface_set_l2_xconnect,                                         \
21842   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21843   "enable | disable")                                                   \
21844 _(sw_interface_set_l2_bridge,                                           \
21845   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21846   "[shg <split-horizon-group>] [bvi]\n"                                 \
21847   "enable | disable")                                                   \
21848 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21849 _(bridge_domain_add_del,                                                \
21850   "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") \
21851 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21852 _(l2fib_add_del,                                                        \
21853   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21854 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21855 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21856 _(l2_flags,                                                             \
21857   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21858 _(bridge_flags,                                                         \
21859   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21860 _(tap_create_v2,                                                        \
21861   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
21862 _(tap_delete_v2,                                                        \
21863   "<vpp-if-name> | sw_if_index <id>")                                   \
21864 _(sw_interface_tap_v2_dump, "")                                         \
21865 _(virtio_pci_create,                                                    \
21866   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21867 _(virtio_pci_delete,                                                    \
21868   "<vpp-if-name> | sw_if_index <id>")                                   \
21869 _(sw_interface_virtio_pci_dump, "")                                     \
21870 _(bond_create,                                                          \
21871   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21872   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21873   "[id <if-id>]")                                                       \
21874 _(bond_delete,                                                          \
21875   "<vpp-if-name> | sw_if_index <id>")                                   \
21876 _(bond_enslave,                                                         \
21877   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21878 _(bond_detach_slave,                                                    \
21879   "sw_if_index <n>")                                                    \
21880 _(sw_interface_bond_dump, "")                                           \
21881 _(sw_interface_slave_dump,                                              \
21882   "<vpp-if-name> | sw_if_index <id>")                                   \
21883 _(ip_table_add_del,                                                     \
21884   "table <n> [ipv6] [add | del]\n")                                     \
21885 _(ip_route_add_del,                                                     \
21886   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21887   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21888   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21889   "[multipath] [count <n>] [del]")                                      \
21890 _(ip_mroute_add_del,                                                    \
21891   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21892   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21893 _(mpls_table_add_del,                                                   \
21894   "table <n> [add | del]\n")                                            \
21895 _(mpls_route_add_del,                                                   \
21896   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21897   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21898   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21899   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21900   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21901   "[count <n>] [del]")                                                  \
21902 _(mpls_ip_bind_unbind,                                                  \
21903   "<label> <addr/len>")                                                 \
21904 _(mpls_tunnel_add_del,                                                  \
21905   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21906   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21907   "[l2-only]  [out-label <n>]")                                         \
21908 _(sr_mpls_policy_add,                                                   \
21909   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21910 _(sr_mpls_policy_del,                                                   \
21911   "bsid <id>")                                                          \
21912 _(bier_table_add_del,                                                   \
21913   "<label> <sub-domain> <set> <bsl> [del]")                             \
21914 _(bier_route_add_del,                                                   \
21915   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21916   "[<intfc> | sw_if_index <id>]"                                        \
21917   "[weight <n>] [del] [multipath]")                                     \
21918 _(proxy_arp_add_del,                                                    \
21919   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21920 _(proxy_arp_intfc_enable_disable,                                       \
21921   "<intfc> | sw_if_index <id> enable | disable")                        \
21922 _(sw_interface_set_unnumbered,                                          \
21923   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21924 _(ip_neighbor_add_del,                                                  \
21925   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21926   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21927 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21928 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21929   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21930   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21931   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21932 _(reset_fib, "vrf <n> [ipv6]")                                          \
21933 _(dhcp_proxy_config,                                                    \
21934   "svr <v46-address> src <v46-address>\n"                               \
21935    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21936 _(dhcp_proxy_set_vss,                                                   \
21937   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21938 _(dhcp_proxy_dump, "ip6")                                               \
21939 _(dhcp_client_config,                                                   \
21940   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21941 _(set_ip_flow_hash,                                                     \
21942   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21943 _(sw_interface_ip6_enable_disable,                                      \
21944   "<intfc> | sw_if_index <id> enable | disable")                        \
21945 _(ip6nd_proxy_add_del,                                                  \
21946   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21947 _(ip6nd_proxy_dump, "")                                                 \
21948 _(sw_interface_ip6nd_ra_prefix,                                         \
21949   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21950   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21951   "[nolink] [isno]")                                                    \
21952 _(sw_interface_ip6nd_ra_config,                                         \
21953   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21954   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21955   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21956 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21957 _(l2_patch_add_del,                                                     \
21958   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21959   "enable | disable")                                                   \
21960 _(sr_localsid_add_del,                                                  \
21961   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21962   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21963 _(classify_add_del_table,                                               \
21964   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21965   " [del] [del-chain] mask <mask-value>\n"                              \
21966   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21967   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21968 _(classify_add_del_session,                                             \
21969   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21970   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21971   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21972   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21973 _(classify_set_interface_ip_table,                                      \
21974   "<intfc> | sw_if_index <nn> table <nn>")                              \
21975 _(classify_set_interface_l2_tables,                                     \
21976   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21977   "  [other-table <nn>]")                                               \
21978 _(get_node_index, "node <node-name")                                    \
21979 _(add_node_next, "node <node-name> next <next-node-name>")              \
21980 _(l2tpv3_create_tunnel,                                                 \
21981   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21982   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21983   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21984 _(l2tpv3_set_tunnel_cookies,                                            \
21985   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21986   "[new_remote_cookie <nn>]\n")                                         \
21987 _(l2tpv3_interface_enable_disable,                                      \
21988   "<intfc> | sw_if_index <nn> enable | disable")                        \
21989 _(l2tpv3_set_lookup_key,                                                \
21990   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21991 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21992 _(vxlan_offload_rx,                                                     \
21993   "hw { <interface name> | hw_if_index <nn>} "                          \
21994   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21995 _(vxlan_add_del_tunnel,                                                 \
21996   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21997   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21998   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21999 _(geneve_add_del_tunnel,                                                \
22000   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22001   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22002   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22003 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22004 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22005 _(gre_tunnel_add_del,                                                   \
22006   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22007   "[teb | erspan <session-id>] [del]")                                  \
22008 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22009 _(l2_fib_clear_table, "")                                               \
22010 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22011 _(l2_interface_vlan_tag_rewrite,                                        \
22012   "<intfc> | sw_if_index <nn> \n"                                       \
22013   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22014   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22015 _(create_vhost_user_if,                                                 \
22016         "socket <filename> [server] [renumber <dev_instance>] "         \
22017         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22018         "[mac <mac_address>]")                                          \
22019 _(modify_vhost_user_if,                                                 \
22020         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22021         "[server] [renumber <dev_instance>]")                           \
22022 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22023 _(sw_interface_vhost_user_dump, "")                                     \
22024 _(show_version, "")                                                     \
22025 _(show_threads, "")                                                     \
22026 _(vxlan_gpe_add_del_tunnel,                                             \
22027   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22028   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22029   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22030   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22031 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22032 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22033 _(interface_name_renumber,                                              \
22034   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22035 _(input_acl_set_interface,                                              \
22036   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22037   "  [l2-table <nn>] [del]")                                            \
22038 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22039 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22040   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22041 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22042 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22043 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22044 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22045 _(ip_dump, "ipv4 | ipv6")                                               \
22046 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22047 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22048   "  spid_id <n> ")                                                     \
22049 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22050   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22051   "  integ_alg <alg> integ_key <hex>")                                  \
22052 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22053   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22054   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22055   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22056 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22057   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22058   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22059   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22060   "  [instance <n>]")     \
22061 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22062 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22063 _(delete_loopback,"sw_if_index <nn>")                                   \
22064 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22065 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22066 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22067 _(want_interface_events,  "enable|disable")                             \
22068 _(get_first_msg_id, "client <name>")                                    \
22069 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22070 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22071   "fib-id <nn> [ip4][ip6][default]")                                    \
22072 _(get_node_graph, " ")                                                  \
22073 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22074 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22075 _(ioam_disable, "")                                                     \
22076 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22077                             " sw_if_index <sw_if_index> p <priority> "  \
22078                             "w <weight>] [del]")                        \
22079 _(one_add_del_locator, "locator-set <locator_name> "                    \
22080                         "iface <intf> | sw_if_index <sw_if_index> "     \
22081                         "p <priority> w <weight> [del]")                \
22082 _(one_add_del_local_eid,"vni <vni> eid "                                \
22083                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22084                          "locator-set <locator_name> [del]"             \
22085                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22086 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22087 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22088 _(one_enable_disable, "enable|disable")                                 \
22089 _(one_map_register_enable_disable, "enable|disable")                    \
22090 _(one_map_register_fallback_threshold, "<value>")                       \
22091 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22092 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22093                                "[seid <seid>] "                         \
22094                                "rloc <locator> p <prio> "               \
22095                                "w <weight> [rloc <loc> ... ] "          \
22096                                "action <action> [del-all]")             \
22097 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22098                           "<local-eid>")                                \
22099 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22100 _(one_use_petr, "ip-address> | disable")                                \
22101 _(one_map_request_mode, "src-dst|dst-only")                             \
22102 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22103 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22104 _(one_locator_set_dump, "[local | remote]")                             \
22105 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22106 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22107                        "[local] | [remote]")                            \
22108 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22109 _(one_ndp_bd_get, "")                                                   \
22110 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22111 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22112 _(one_l2_arp_bd_get, "")                                                \
22113 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22114 _(one_stats_enable_disable, "enable|disable")                           \
22115 _(show_one_stats_enable_disable, "")                                    \
22116 _(one_eid_table_vni_dump, "")                                           \
22117 _(one_eid_table_map_dump, "l2|l3")                                      \
22118 _(one_map_resolver_dump, "")                                            \
22119 _(one_map_server_dump, "")                                              \
22120 _(one_adjacencies_get, "vni <vni>")                                     \
22121 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22122 _(show_one_rloc_probe_state, "")                                        \
22123 _(show_one_map_register_state, "")                                      \
22124 _(show_one_status, "")                                                  \
22125 _(one_stats_dump, "")                                                   \
22126 _(one_stats_flush, "")                                                  \
22127 _(one_get_map_request_itr_rlocs, "")                                    \
22128 _(one_map_register_set_ttl, "<ttl>")                                    \
22129 _(one_set_transport_protocol, "udp|api")                                \
22130 _(one_get_transport_protocol, "")                                       \
22131 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22132 _(one_show_xtr_mode, "")                                                \
22133 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22134 _(one_show_pitr_mode, "")                                               \
22135 _(one_enable_disable_petr_mode, "enable|disable")                       \
22136 _(one_show_petr_mode, "")                                               \
22137 _(show_one_nsh_mapping, "")                                             \
22138 _(show_one_pitr, "")                                                    \
22139 _(show_one_use_petr, "")                                                \
22140 _(show_one_map_request_mode, "")                                        \
22141 _(show_one_map_register_ttl, "")                                        \
22142 _(show_one_map_register_fallback_threshold, "")                         \
22143 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22144                             " sw_if_index <sw_if_index> p <priority> "  \
22145                             "w <weight>] [del]")                        \
22146 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22147                         "iface <intf> | sw_if_index <sw_if_index> "     \
22148                         "p <priority> w <weight> [del]")                \
22149 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22150                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22151                          "locator-set <locator_name> [del]"             \
22152                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22153 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22154 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22155 _(lisp_enable_disable, "enable|disable")                                \
22156 _(lisp_map_register_enable_disable, "enable|disable")                   \
22157 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22158 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22159                                "[seid <seid>] "                         \
22160                                "rloc <locator> p <prio> "               \
22161                                "w <weight> [rloc <loc> ... ] "          \
22162                                "action <action> [del-all]")             \
22163 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22164                           "<local-eid>")                                \
22165 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22166 _(lisp_use_petr, "<ip-address> | disable")                              \
22167 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22168 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22169 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22170 _(lisp_locator_set_dump, "[local | remote]")                            \
22171 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22172 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22173                        "[local] | [remote]")                            \
22174 _(lisp_eid_table_vni_dump, "")                                          \
22175 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22176 _(lisp_map_resolver_dump, "")                                           \
22177 _(lisp_map_server_dump, "")                                             \
22178 _(lisp_adjacencies_get, "vni <vni>")                                    \
22179 _(gpe_fwd_entry_vnis_get, "")                                           \
22180 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22181 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22182                                 "[table <table-id>]")                   \
22183 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22184 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22185 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22186 _(gpe_get_encap_mode, "")                                               \
22187 _(lisp_gpe_add_del_iface, "up|down")                                    \
22188 _(lisp_gpe_enable_disable, "enable|disable")                            \
22189 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22190   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22191 _(show_lisp_rloc_probe_state, "")                                       \
22192 _(show_lisp_map_register_state, "")                                     \
22193 _(show_lisp_status, "")                                                 \
22194 _(lisp_get_map_request_itr_rlocs, "")                                   \
22195 _(show_lisp_pitr, "")                                                   \
22196 _(show_lisp_use_petr, "")                                               \
22197 _(show_lisp_map_request_mode, "")                                       \
22198 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22199 _(af_packet_delete, "name <host interface name>")                       \
22200 _(af_packet_dump, "")                                                   \
22201 _(policer_add_del, "name <policer name> <params> [del]")                \
22202 _(policer_dump, "[name <policer name>]")                                \
22203 _(policer_classify_set_interface,                                       \
22204   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22205   "  [l2-table <nn>] [del]")                                            \
22206 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22207 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22208     "[master|slave]")                                                   \
22209 _(netmap_delete, "name <interface name>")                               \
22210 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22211 _(mpls_table_dump, "")                                                  \
22212 _(mpls_route_dump, "table-id <ID>")                                     \
22213 _(classify_table_ids, "")                                               \
22214 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22215 _(classify_table_info, "table_id <nn>")                                 \
22216 _(classify_session_dump, "table_id <nn>")                               \
22217 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22218     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22219     "[template_interval <nn>] [udp_checksum]")                          \
22220 _(ipfix_exporter_dump, "")                                              \
22221 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22222 _(ipfix_classify_stream_dump, "")                                       \
22223 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22224 _(ipfix_classify_table_dump, "")                                        \
22225 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22226 _(sw_interface_span_dump, "[l2]")                                           \
22227 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22228 _(pg_create_interface, "if_id <nn>")                                    \
22229 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22230 _(pg_enable_disable, "[stream <id>] disable")                           \
22231 _(ip_source_and_port_range_check_add_del,                               \
22232   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22233 _(ip_source_and_port_range_check_interface_add_del,                     \
22234   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22235   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22236 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22237 _(l2_interface_pbb_tag_rewrite,                                         \
22238   "<intfc> | sw_if_index <nn> \n"                                       \
22239   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22240   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22241 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22242 _(flow_classify_set_interface,                                          \
22243   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22244 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22245 _(ip_table_dump, "")                                                    \
22246 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22247 _(ip_mtable_dump, "")                                                   \
22248 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22249 _(feature_enable_disable, "arc_name <arc_name> "                        \
22250   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22251 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22252 "[disable]")                                                            \
22253 _(l2_xconnect_dump, "")                                                 \
22254 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22255 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22256 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22257 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22258 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22259 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22260 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22261   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22262 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22263 _(sock_init_shm, "size <nnn>")                                          \
22264 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22265 _(dns_enable_disable, "[enable][disable]")                              \
22266 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22267 _(dns_resolve_name, "<hostname>")                                       \
22268 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22269 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22270 _(dns_resolve_name, "<hostname>")                                       \
22271 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22272   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22273 _(session_rules_dump, "")                                               \
22274 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22275 _(output_acl_set_interface,                                             \
22276   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22277   "  [l2-table <nn>] [del]")                                            \
22278 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22279
22280 /* List of command functions, CLI names map directly to functions */
22281 #define foreach_cli_function                                    \
22282 _(comment, "usage: comment <ignore-rest-of-line>")              \
22283 _(dump_interface_table, "usage: dump_interface_table")          \
22284 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22285 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22286 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22287 _(dump_macro_table, "usage: dump_macro_table ")                 \
22288 _(dump_node_table, "usage: dump_node_table")                    \
22289 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22290 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22291 _(echo, "usage: echo <message>")                                \
22292 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22293 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22294 _(help, "usage: help")                                          \
22295 _(q, "usage: quit")                                             \
22296 _(quit, "usage: quit")                                          \
22297 _(search_node_table, "usage: search_node_table <name>...")      \
22298 _(set, "usage: set <variable-name> <value>")                    \
22299 _(script, "usage: script <file-name>")                          \
22300 _(statseg, "usage: statseg")                                    \
22301 _(unset, "usage: unset <variable-name>")
22302
22303 #define _(N,n)                                  \
22304     static void vl_api_##n##_t_handler_uni      \
22305     (vl_api_##n##_t * mp)                       \
22306     {                                           \
22307         vat_main_t * vam = &vat_main;           \
22308         if (vam->json_output) {                 \
22309             vl_api_##n##_t_handler_json(mp);    \
22310         } else {                                \
22311             vl_api_##n##_t_handler(mp);         \
22312         }                                       \
22313     }
22314 foreach_vpe_api_reply_msg;
22315 #if VPP_API_TEST_BUILTIN == 0
22316 foreach_standalone_reply_msg;
22317 #endif
22318 #undef _
22319
22320 void
22321 vat_api_hookup (vat_main_t * vam)
22322 {
22323 #define _(N,n)                                                  \
22324     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22325                            vl_api_##n##_t_handler_uni,          \
22326                            vl_noop_handler,                     \
22327                            vl_api_##n##_t_endian,               \
22328                            vl_api_##n##_t_print,                \
22329                            sizeof(vl_api_##n##_t), 1);
22330   foreach_vpe_api_reply_msg;
22331 #if VPP_API_TEST_BUILTIN == 0
22332   foreach_standalone_reply_msg;
22333 #endif
22334 #undef _
22335
22336 #if (VPP_API_TEST_BUILTIN==0)
22337   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22338
22339   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22340
22341   vam->function_by_name = hash_create_string (0, sizeof (uword));
22342
22343   vam->help_by_name = hash_create_string (0, sizeof (uword));
22344 #endif
22345
22346   /* API messages we can send */
22347 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22348   foreach_vpe_api_msg;
22349 #undef _
22350
22351   /* Help strings */
22352 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22353   foreach_vpe_api_msg;
22354 #undef _
22355
22356   /* CLI functions */
22357 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22358   foreach_cli_function;
22359 #undef _
22360
22361   /* Help strings */
22362 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22363   foreach_cli_function;
22364 #undef _
22365 }
22366
22367 #if VPP_API_TEST_BUILTIN
22368 static clib_error_t *
22369 vat_api_hookup_shim (vlib_main_t * vm)
22370 {
22371   vat_api_hookup (&vat_main);
22372   return 0;
22373 }
22374
22375 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22376 #endif
22377
22378 /*
22379  * fd.io coding-style-patch-verification: ON
22380  *
22381  * Local Variables:
22382  * eval: (c-set-style "gnu")
22383  * End:
22384  */