fib: fib api updates
[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_ipsec_gre_tunnel_add_del_reply_t_handler
5088   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091   i32 retval = ntohl (mp->retval);
5092   if (vam->async_mode)
5093     {
5094       vam->async_errors += (retval < 0);
5095     }
5096   else
5097     {
5098       vam->retval = retval;
5099       vam->sw_if_index = ntohl (mp->sw_if_index);
5100       vam->result_ready = 1;
5101     }
5102   vam->regenerate_interface_table = 1;
5103 }
5104
5105 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5106   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t node;
5110
5111   vat_json_init_object (&node);
5112   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5113   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5114
5115   vat_json_print (vam->ofp, &node);
5116   vat_json_free (&node);
5117
5118   vam->retval = ntohl (mp->retval);
5119   vam->result_ready = 1;
5120 }
5121
5122 static void vl_api_flow_classify_details_t_handler
5123   (vl_api_flow_classify_details_t * mp)
5124 {
5125   vat_main_t *vam = &vat_main;
5126
5127   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5128          ntohl (mp->table_index));
5129 }
5130
5131 static void vl_api_flow_classify_details_t_handler_json
5132   (vl_api_flow_classify_details_t * mp)
5133 {
5134   vat_main_t *vam = &vat_main;
5135   vat_json_node_t *node;
5136
5137   if (VAT_JSON_ARRAY != vam->json_tree.type)
5138     {
5139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5140       vat_json_init_array (&vam->json_tree);
5141     }
5142   node = vat_json_array_add (&vam->json_tree);
5143
5144   vat_json_init_object (node);
5145   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5146   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5147 }
5148
5149 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5150 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5151 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5152 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5153 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5154 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5155 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5156 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5157 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5158 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5159
5160 /*
5161  * Generate boilerplate reply handlers, which
5162  * dig the return value out of the xxx_reply_t API message,
5163  * stick it into vam->retval, and set vam->result_ready
5164  *
5165  * Could also do this by pointing N message decode slots at
5166  * a single function, but that could break in subtle ways.
5167  */
5168
5169 #define foreach_standard_reply_retval_handler           \
5170 _(sw_interface_set_flags_reply)                         \
5171 _(sw_interface_add_del_address_reply)                   \
5172 _(sw_interface_set_rx_mode_reply)                       \
5173 _(sw_interface_set_rx_placement_reply)                  \
5174 _(sw_interface_set_table_reply)                         \
5175 _(sw_interface_set_mpls_enable_reply)                   \
5176 _(sw_interface_set_vpath_reply)                         \
5177 _(sw_interface_set_vxlan_bypass_reply)                  \
5178 _(sw_interface_set_geneve_bypass_reply)                 \
5179 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5180 _(sw_interface_set_l2_bridge_reply)                     \
5181 _(bridge_domain_add_del_reply)                          \
5182 _(sw_interface_set_l2_xconnect_reply)                   \
5183 _(l2fib_add_del_reply)                                  \
5184 _(l2fib_flush_int_reply)                                \
5185 _(l2fib_flush_bd_reply)                                 \
5186 _(ip_route_add_del_reply)                               \
5187 _(ip_table_add_del_reply)                               \
5188 _(ip_mroute_add_del_reply)                              \
5189 _(mpls_route_add_del_reply)                             \
5190 _(mpls_table_add_del_reply)                             \
5191 _(mpls_ip_bind_unbind_reply)                            \
5192 _(bier_route_add_del_reply)                             \
5193 _(bier_table_add_del_reply)                             \
5194 _(proxy_arp_add_del_reply)                              \
5195 _(proxy_arp_intfc_enable_disable_reply)                 \
5196 _(sw_interface_set_unnumbered_reply)                    \
5197 _(ip_neighbor_add_del_reply)                            \
5198 _(reset_fib_reply)                                      \
5199 _(dhcp_proxy_config_reply)                              \
5200 _(dhcp_proxy_set_vss_reply)                             \
5201 _(dhcp_client_config_reply)                             \
5202 _(set_ip_flow_hash_reply)                               \
5203 _(sw_interface_ip6_enable_disable_reply)                \
5204 _(ip6nd_proxy_add_del_reply)                            \
5205 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5206 _(sw_interface_ip6nd_ra_config_reply)                   \
5207 _(set_arp_neighbor_limit_reply)                         \
5208 _(l2_patch_add_del_reply)                               \
5209 _(sr_mpls_policy_add_reply)                             \
5210 _(sr_mpls_policy_mod_reply)                             \
5211 _(sr_mpls_policy_del_reply)                             \
5212 _(sr_policy_add_reply)                                  \
5213 _(sr_policy_mod_reply)                                  \
5214 _(sr_policy_del_reply)                                  \
5215 _(sr_localsid_add_del_reply)                            \
5216 _(sr_steering_add_del_reply)                            \
5217 _(classify_add_del_session_reply)                       \
5218 _(classify_set_interface_ip_table_reply)                \
5219 _(classify_set_interface_l2_tables_reply)               \
5220 _(l2tpv3_set_tunnel_cookies_reply)                      \
5221 _(l2tpv3_interface_enable_disable_reply)                \
5222 _(l2tpv3_set_lookup_key_reply)                          \
5223 _(l2_fib_clear_table_reply)                             \
5224 _(l2_interface_efp_filter_reply)                        \
5225 _(l2_interface_vlan_tag_rewrite_reply)                  \
5226 _(modify_vhost_user_if_reply)                           \
5227 _(delete_vhost_user_if_reply)                           \
5228 _(ip_probe_neighbor_reply)                              \
5229 _(ip_scan_neighbor_enable_disable_reply)                \
5230 _(want_ip4_arp_events_reply)                            \
5231 _(want_ip6_nd_events_reply)                             \
5232 _(want_l2_macs_events_reply)                            \
5233 _(input_acl_set_interface_reply)                        \
5234 _(ipsec_spd_add_del_reply)                              \
5235 _(ipsec_interface_add_del_spd_reply)                    \
5236 _(ipsec_spd_entry_add_del_reply)                        \
5237 _(ipsec_sad_entry_add_del_reply)                        \
5238 _(ipsec_tunnel_if_add_del_reply)                        \
5239 _(ipsec_tunnel_if_set_sa_reply)                         \
5240 _(delete_loopback_reply)                                \
5241 _(bd_ip_mac_add_del_reply)                              \
5242 _(bd_ip_mac_flush_reply)                                \
5243 _(want_interface_events_reply)                          \
5244 _(cop_interface_enable_disable_reply)                   \
5245 _(cop_whitelist_enable_disable_reply)                   \
5246 _(sw_interface_clear_stats_reply)                       \
5247 _(ioam_enable_reply)                                    \
5248 _(ioam_disable_reply)                                   \
5249 _(one_add_del_locator_reply)                            \
5250 _(one_add_del_local_eid_reply)                          \
5251 _(one_add_del_remote_mapping_reply)                     \
5252 _(one_add_del_adjacency_reply)                          \
5253 _(one_add_del_map_resolver_reply)                       \
5254 _(one_add_del_map_server_reply)                         \
5255 _(one_enable_disable_reply)                             \
5256 _(one_rloc_probe_enable_disable_reply)                  \
5257 _(one_map_register_enable_disable_reply)                \
5258 _(one_map_register_set_ttl_reply)                       \
5259 _(one_set_transport_protocol_reply)                     \
5260 _(one_map_register_fallback_threshold_reply)            \
5261 _(one_pitr_set_locator_set_reply)                       \
5262 _(one_map_request_mode_reply)                           \
5263 _(one_add_del_map_request_itr_rlocs_reply)              \
5264 _(one_eid_table_add_del_map_reply)                      \
5265 _(one_use_petr_reply)                                   \
5266 _(one_stats_enable_disable_reply)                       \
5267 _(one_add_del_l2_arp_entry_reply)                       \
5268 _(one_add_del_ndp_entry_reply)                          \
5269 _(one_stats_flush_reply)                                \
5270 _(one_enable_disable_xtr_mode_reply)                    \
5271 _(one_enable_disable_pitr_mode_reply)                   \
5272 _(one_enable_disable_petr_mode_reply)                   \
5273 _(gpe_enable_disable_reply)                             \
5274 _(gpe_set_encap_mode_reply)                             \
5275 _(gpe_add_del_iface_reply)                              \
5276 _(gpe_add_del_native_fwd_rpath_reply)                   \
5277 _(af_packet_delete_reply)                               \
5278 _(policer_classify_set_interface_reply)                 \
5279 _(netmap_create_reply)                                  \
5280 _(netmap_delete_reply)                                  \
5281 _(set_ipfix_exporter_reply)                             \
5282 _(set_ipfix_classify_stream_reply)                      \
5283 _(ipfix_classify_table_add_del_reply)                   \
5284 _(flow_classify_set_interface_reply)                    \
5285 _(sw_interface_span_enable_disable_reply)               \
5286 _(pg_capture_reply)                                     \
5287 _(pg_enable_disable_reply)                              \
5288 _(ip_source_and_port_range_check_add_del_reply)         \
5289 _(ip_source_and_port_range_check_interface_add_del_reply)\
5290 _(delete_subif_reply)                                   \
5291 _(l2_interface_pbb_tag_rewrite_reply)                   \
5292 _(set_punt_reply)                                       \
5293 _(feature_enable_disable_reply)                         \
5294 _(sw_interface_tag_add_del_reply)                       \
5295 _(hw_interface_set_mtu_reply)                           \
5296 _(p2p_ethernet_add_reply)                               \
5297 _(p2p_ethernet_del_reply)                               \
5298 _(lldp_config_reply)                                    \
5299 _(sw_interface_set_lldp_reply)                          \
5300 _(tcp_configure_src_addresses_reply)                    \
5301 _(dns_enable_disable_reply)                             \
5302 _(dns_name_server_add_del_reply)                        \
5303 _(session_rule_add_del_reply)                           \
5304 _(ip_container_proxy_add_del_reply)                     \
5305 _(output_acl_set_interface_reply)                       \
5306 _(qos_record_enable_disable_reply)
5307
5308 #define _(n)                                    \
5309     static void vl_api_##n##_t_handler          \
5310     (vl_api_##n##_t * mp)                       \
5311     {                                           \
5312         vat_main_t * vam = &vat_main;           \
5313         i32 retval = ntohl(mp->retval);         \
5314         if (vam->async_mode) {                  \
5315             vam->async_errors += (retval < 0);  \
5316         } else {                                \
5317             vam->retval = retval;               \
5318             vam->result_ready = 1;              \
5319         }                                       \
5320     }
5321 foreach_standard_reply_retval_handler;
5322 #undef _
5323
5324 #define _(n)                                    \
5325     static void vl_api_##n##_t_handler_json     \
5326     (vl_api_##n##_t * mp)                       \
5327     {                                           \
5328         vat_main_t * vam = &vat_main;           \
5329         vat_json_node_t node;                   \
5330         vat_json_init_object(&node);            \
5331         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5332         vat_json_print(vam->ofp, &node);        \
5333         vam->retval = ntohl(mp->retval);        \
5334         vam->result_ready = 1;                  \
5335     }
5336 foreach_standard_reply_retval_handler;
5337 #undef _
5338
5339 /*
5340  * Table of message reply handlers, must include boilerplate handlers
5341  * we just generated
5342  */
5343
5344 #define foreach_vpe_api_reply_msg                                       \
5345 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5346 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5347 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5348 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5349 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5350 _(CLI_REPLY, cli_reply)                                                 \
5351 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5352 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5353   sw_interface_add_del_address_reply)                                   \
5354 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5355 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5356 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5357 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5358 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5359 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5360 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5361 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5362 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5363 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5364   sw_interface_set_l2_xconnect_reply)                                   \
5365 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5366   sw_interface_set_l2_bridge_reply)                                     \
5367 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5368 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5369 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5370 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5371 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5372 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5373 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5374 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5375 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5376 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5377 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5378 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5379 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5380 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5381 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5382 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5383 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5384 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5385 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5386 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5387 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5388 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5389 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5390 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5391 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5392 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5393 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5394 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5395 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5396 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5397   proxy_arp_intfc_enable_disable_reply)                                 \
5398 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5399 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5400   sw_interface_set_unnumbered_reply)                                    \
5401 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5402 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5403 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5404 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5405 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5406 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5407 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5408 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5409 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5410 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5411   sw_interface_ip6_enable_disable_reply)                                \
5412 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5413 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5414 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5415   sw_interface_ip6nd_ra_prefix_reply)                                   \
5416 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5417   sw_interface_ip6nd_ra_config_reply)                                   \
5418 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5419 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5420 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5421 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5422 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5423 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5424 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5425 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5426 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5427 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5428 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5429 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5430 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5431 classify_set_interface_ip_table_reply)                                  \
5432 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5433   classify_set_interface_l2_tables_reply)                               \
5434 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5435 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5436 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5437 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5438 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5439   l2tpv3_interface_enable_disable_reply)                                \
5440 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5441 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5442 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5443 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5444 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5445 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5446 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5447 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5448 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5449 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5450 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5451 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5452 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5453 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5454 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5455 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5456 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5457 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5458 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5459 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5460 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5461 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5462 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5463 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5464 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5465 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5466 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5467 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5468 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5469 _(L2_MACS_EVENT, l2_macs_event)                                         \
5470 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5471 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5472 _(IP_DETAILS, ip_details)                                               \
5473 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5474 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5475 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5476 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5477 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5478 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5479 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5480 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5481 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5482 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5483 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5484 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5485 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5486 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5487 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5488 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5489 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5490 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5491 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5492 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5493 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5494 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5495 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5496 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5497 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5498 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5499 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5500 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5501 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5502   one_map_register_enable_disable_reply)                                \
5503 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5504 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5505 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5506 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5507   one_map_register_fallback_threshold_reply)                            \
5508 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5509   one_rloc_probe_enable_disable_reply)                                  \
5510 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5511 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5512 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5513 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5514 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5515 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5516 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5517 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5518 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5519 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5520 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5521 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5522 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5523 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5524 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5525 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5526   show_one_stats_enable_disable_reply)                                  \
5527 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5528 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5529 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5530 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5531 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5532 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5533 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5534 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5535   one_enable_disable_pitr_mode_reply)                                   \
5536 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5537   one_enable_disable_petr_mode_reply)                                   \
5538 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5539 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5540 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5541 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5542 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5543 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5544 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5545 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5546 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5547 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5548 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5549 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5550   gpe_add_del_native_fwd_rpath_reply)                                   \
5551 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5552   gpe_fwd_entry_path_details)                                           \
5553 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5554 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5555   one_add_del_map_request_itr_rlocs_reply)                              \
5556 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5557   one_get_map_request_itr_rlocs_reply)                                  \
5558 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5559 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5560 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5561 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5562 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5563 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5564   show_one_map_register_state_reply)                                    \
5565 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5566 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5567   show_one_map_register_fallback_threshold_reply)                       \
5568 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5569 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5570 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5571 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5572 _(POLICER_DETAILS, policer_details)                                     \
5573 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5574 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5575 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5576 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5577 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5578 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5579 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5580 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5581 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5582 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5583 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5584 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5585 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5586 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5587 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5588 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5589 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5590 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5591 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5592 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5593 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5594 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5595 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5596 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5597 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5598 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5599  ip_source_and_port_range_check_add_del_reply)                          \
5600 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5601  ip_source_and_port_range_check_interface_add_del_reply)                \
5602 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5603 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5604 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5605 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5606 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5607 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5608 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5609 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5610 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5611 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5612 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5613 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5614 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5615 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5616 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5617 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5618 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5619 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5620 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5621 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5622 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5623 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5624 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5625 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5626 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5627 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5628 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5629 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5630
5631 #define foreach_standalone_reply_msg                                    \
5632 _(SW_INTERFACE_EVENT, sw_interface_event)
5633
5634 typedef struct
5635 {
5636   u8 *name;
5637   u32 value;
5638 } name_sort_t;
5639
5640 #define STR_VTR_OP_CASE(op)     \
5641     case L2_VTR_ ## op:         \
5642         return "" # op;
5643
5644 static const char *
5645 str_vtr_op (u32 vtr_op)
5646 {
5647   switch (vtr_op)
5648     {
5649       STR_VTR_OP_CASE (DISABLED);
5650       STR_VTR_OP_CASE (PUSH_1);
5651       STR_VTR_OP_CASE (PUSH_2);
5652       STR_VTR_OP_CASE (POP_1);
5653       STR_VTR_OP_CASE (POP_2);
5654       STR_VTR_OP_CASE (TRANSLATE_1_1);
5655       STR_VTR_OP_CASE (TRANSLATE_1_2);
5656       STR_VTR_OP_CASE (TRANSLATE_2_1);
5657       STR_VTR_OP_CASE (TRANSLATE_2_2);
5658     }
5659
5660   return "UNKNOWN";
5661 }
5662
5663 static int
5664 dump_sub_interface_table (vat_main_t * vam)
5665 {
5666   const sw_interface_subif_t *sub = NULL;
5667
5668   if (vam->json_output)
5669     {
5670       clib_warning
5671         ("JSON output supported only for VPE API calls and dump_stats_table");
5672       return -99;
5673     }
5674
5675   print (vam->ofp,
5676          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5677          "Interface", "sw_if_index",
5678          "sub id", "dot1ad", "tags", "outer id",
5679          "inner id", "exact", "default", "outer any", "inner any");
5680
5681   vec_foreach (sub, vam->sw_if_subif_table)
5682   {
5683     print (vam->ofp,
5684            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5685            sub->interface_name,
5686            sub->sw_if_index,
5687            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5688            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5689            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5690            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5691     if (sub->vtr_op != L2_VTR_DISABLED)
5692       {
5693         print (vam->ofp,
5694                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5695                "tag1: %d tag2: %d ]",
5696                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5697                sub->vtr_tag1, sub->vtr_tag2);
5698       }
5699   }
5700
5701   return 0;
5702 }
5703
5704 static int
5705 name_sort_cmp (void *a1, void *a2)
5706 {
5707   name_sort_t *n1 = a1;
5708   name_sort_t *n2 = a2;
5709
5710   return strcmp ((char *) n1->name, (char *) n2->name);
5711 }
5712
5713 static int
5714 dump_interface_table (vat_main_t * vam)
5715 {
5716   hash_pair_t *p;
5717   name_sort_t *nses = 0, *ns;
5718
5719   if (vam->json_output)
5720     {
5721       clib_warning
5722         ("JSON output supported only for VPE API calls and dump_stats_table");
5723       return -99;
5724     }
5725
5726   /* *INDENT-OFF* */
5727   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5728   ({
5729     vec_add2 (nses, ns, 1);
5730     ns->name = (u8 *)(p->key);
5731     ns->value = (u32) p->value[0];
5732   }));
5733   /* *INDENT-ON* */
5734
5735   vec_sort_with_function (nses, name_sort_cmp);
5736
5737   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5738   vec_foreach (ns, nses)
5739   {
5740     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5741   }
5742   vec_free (nses);
5743   return 0;
5744 }
5745
5746 static int
5747 dump_ip_table (vat_main_t * vam, int is_ipv6)
5748 {
5749   const ip_details_t *det = NULL;
5750   const ip_address_details_t *address = NULL;
5751   u32 i = ~0;
5752
5753   print (vam->ofp, "%-12s", "sw_if_index");
5754
5755   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5756   {
5757     i++;
5758     if (!det->present)
5759       {
5760         continue;
5761       }
5762     print (vam->ofp, "%-12d", i);
5763     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5764     if (!det->addr)
5765       {
5766         continue;
5767       }
5768     vec_foreach (address, det->addr)
5769     {
5770       print (vam->ofp,
5771              "            %-30U%-13d",
5772              is_ipv6 ? format_ip6_address : format_ip4_address,
5773              address->ip, address->prefix_length);
5774     }
5775   }
5776
5777   return 0;
5778 }
5779
5780 static int
5781 dump_ipv4_table (vat_main_t * vam)
5782 {
5783   if (vam->json_output)
5784     {
5785       clib_warning
5786         ("JSON output supported only for VPE API calls and dump_stats_table");
5787       return -99;
5788     }
5789
5790   return dump_ip_table (vam, 0);
5791 }
5792
5793 static int
5794 dump_ipv6_table (vat_main_t * vam)
5795 {
5796   if (vam->json_output)
5797     {
5798       clib_warning
5799         ("JSON output supported only for VPE API calls and dump_stats_table");
5800       return -99;
5801     }
5802
5803   return dump_ip_table (vam, 1);
5804 }
5805
5806 /*
5807  * Pass CLI buffers directly in the CLI_INBAND API message,
5808  * instead of an additional shared memory area.
5809  */
5810 static int
5811 exec_inband (vat_main_t * vam)
5812 {
5813   vl_api_cli_inband_t *mp;
5814   unformat_input_t *i = vam->input;
5815   int ret;
5816
5817   if (vec_len (i->buffer) == 0)
5818     return -1;
5819
5820   if (vam->exec_mode == 0 && unformat (i, "mode"))
5821     {
5822       vam->exec_mode = 1;
5823       return 0;
5824     }
5825   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5826     {
5827       vam->exec_mode = 0;
5828       return 0;
5829     }
5830
5831   /*
5832    * In order for the CLI command to work, it
5833    * must be a vector ending in \n, not a C-string ending
5834    * in \n\0.
5835    */
5836   u32 len = vec_len (vam->input->buffer);
5837   M2 (CLI_INBAND, mp, len);
5838   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5839
5840   S (mp);
5841   W (ret);
5842   /* json responses may or may not include a useful reply... */
5843   if (vec_len (vam->cmd_reply))
5844     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5845   return ret;
5846 }
5847
5848 int
5849 exec (vat_main_t * vam)
5850 {
5851   return exec_inband (vam);
5852 }
5853
5854 static int
5855 api_create_loopback (vat_main_t * vam)
5856 {
5857   unformat_input_t *i = vam->input;
5858   vl_api_create_loopback_t *mp;
5859   vl_api_create_loopback_instance_t *mp_lbi;
5860   u8 mac_address[6];
5861   u8 mac_set = 0;
5862   u8 is_specified = 0;
5863   u32 user_instance = 0;
5864   int ret;
5865
5866   clib_memset (mac_address, 0, sizeof (mac_address));
5867
5868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5869     {
5870       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5871         mac_set = 1;
5872       if (unformat (i, "instance %d", &user_instance))
5873         is_specified = 1;
5874       else
5875         break;
5876     }
5877
5878   if (is_specified)
5879     {
5880       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5881       mp_lbi->is_specified = is_specified;
5882       if (is_specified)
5883         mp_lbi->user_instance = htonl (user_instance);
5884       if (mac_set)
5885         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5886       S (mp_lbi);
5887     }
5888   else
5889     {
5890       /* Construct the API message */
5891       M (CREATE_LOOPBACK, mp);
5892       if (mac_set)
5893         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5894       S (mp);
5895     }
5896
5897   W (ret);
5898   return ret;
5899 }
5900
5901 static int
5902 api_delete_loopback (vat_main_t * vam)
5903 {
5904   unformat_input_t *i = vam->input;
5905   vl_api_delete_loopback_t *mp;
5906   u32 sw_if_index = ~0;
5907   int ret;
5908
5909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5910     {
5911       if (unformat (i, "sw_if_index %d", &sw_if_index))
5912         ;
5913       else
5914         break;
5915     }
5916
5917   if (sw_if_index == ~0)
5918     {
5919       errmsg ("missing sw_if_index");
5920       return -99;
5921     }
5922
5923   /* Construct the API message */
5924   M (DELETE_LOOPBACK, mp);
5925   mp->sw_if_index = ntohl (sw_if_index);
5926
5927   S (mp);
5928   W (ret);
5929   return ret;
5930 }
5931
5932 static int
5933 api_want_interface_events (vat_main_t * vam)
5934 {
5935   unformat_input_t *i = vam->input;
5936   vl_api_want_interface_events_t *mp;
5937   int enable = -1;
5938   int ret;
5939
5940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5941     {
5942       if (unformat (i, "enable"))
5943         enable = 1;
5944       else if (unformat (i, "disable"))
5945         enable = 0;
5946       else
5947         break;
5948     }
5949
5950   if (enable == -1)
5951     {
5952       errmsg ("missing enable|disable");
5953       return -99;
5954     }
5955
5956   M (WANT_INTERFACE_EVENTS, mp);
5957   mp->enable_disable = enable;
5958
5959   vam->interface_event_display = enable;
5960
5961   S (mp);
5962   W (ret);
5963   return ret;
5964 }
5965
5966
5967 /* Note: non-static, called once to set up the initial intfc table */
5968 int
5969 api_sw_interface_dump (vat_main_t * vam)
5970 {
5971   vl_api_sw_interface_dump_t *mp;
5972   vl_api_control_ping_t *mp_ping;
5973   hash_pair_t *p;
5974   name_sort_t *nses = 0, *ns;
5975   sw_interface_subif_t *sub = NULL;
5976   int ret;
5977
5978   /* Toss the old name table */
5979   /* *INDENT-OFF* */
5980   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5981   ({
5982     vec_add2 (nses, ns, 1);
5983     ns->name = (u8 *)(p->key);
5984     ns->value = (u32) p->value[0];
5985   }));
5986   /* *INDENT-ON* */
5987
5988   hash_free (vam->sw_if_index_by_interface_name);
5989
5990   vec_foreach (ns, nses) vec_free (ns->name);
5991
5992   vec_free (nses);
5993
5994   vec_foreach (sub, vam->sw_if_subif_table)
5995   {
5996     vec_free (sub->interface_name);
5997   }
5998   vec_free (vam->sw_if_subif_table);
5999
6000   /* recreate the interface name hash table */
6001   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6002
6003   /*
6004    * Ask for all interface names. Otherwise, the epic catalog of
6005    * name filters becomes ridiculously long, and vat ends up needing
6006    * to be taught about new interface types.
6007    */
6008   M (SW_INTERFACE_DUMP, mp);
6009   S (mp);
6010
6011   /* Use a control ping for synchronization */
6012   MPING (CONTROL_PING, mp_ping);
6013   S (mp_ping);
6014
6015   W (ret);
6016   return ret;
6017 }
6018
6019 static int
6020 api_sw_interface_set_flags (vat_main_t * vam)
6021 {
6022   unformat_input_t *i = vam->input;
6023   vl_api_sw_interface_set_flags_t *mp;
6024   u32 sw_if_index;
6025   u8 sw_if_index_set = 0;
6026   u8 admin_up = 0;
6027   int ret;
6028
6029   /* Parse args required to build the message */
6030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6031     {
6032       if (unformat (i, "admin-up"))
6033         admin_up = 1;
6034       else if (unformat (i, "admin-down"))
6035         admin_up = 0;
6036       else
6037         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6038         sw_if_index_set = 1;
6039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6040         sw_if_index_set = 1;
6041       else
6042         break;
6043     }
6044
6045   if (sw_if_index_set == 0)
6046     {
6047       errmsg ("missing interface name or sw_if_index");
6048       return -99;
6049     }
6050
6051   /* Construct the API message */
6052   M (SW_INTERFACE_SET_FLAGS, mp);
6053   mp->sw_if_index = ntohl (sw_if_index);
6054   mp->admin_up_down = admin_up;
6055
6056   /* send it... */
6057   S (mp);
6058
6059   /* Wait for a reply, return the good/bad news... */
6060   W (ret);
6061   return ret;
6062 }
6063
6064 static int
6065 api_sw_interface_set_rx_mode (vat_main_t * vam)
6066 {
6067   unformat_input_t *i = vam->input;
6068   vl_api_sw_interface_set_rx_mode_t *mp;
6069   u32 sw_if_index;
6070   u8 sw_if_index_set = 0;
6071   int ret;
6072   u8 queue_id_valid = 0;
6073   u32 queue_id;
6074   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6075
6076   /* Parse args required to build the message */
6077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6078     {
6079       if (unformat (i, "queue %d", &queue_id))
6080         queue_id_valid = 1;
6081       else if (unformat (i, "polling"))
6082         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6083       else if (unformat (i, "interrupt"))
6084         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6085       else if (unformat (i, "adaptive"))
6086         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6087       else
6088         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6089         sw_if_index_set = 1;
6090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6091         sw_if_index_set = 1;
6092       else
6093         break;
6094     }
6095
6096   if (sw_if_index_set == 0)
6097     {
6098       errmsg ("missing interface name or sw_if_index");
6099       return -99;
6100     }
6101   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6102     {
6103       errmsg ("missing rx-mode");
6104       return -99;
6105     }
6106
6107   /* Construct the API message */
6108   M (SW_INTERFACE_SET_RX_MODE, mp);
6109   mp->sw_if_index = ntohl (sw_if_index);
6110   mp->mode = mode;
6111   mp->queue_id_valid = queue_id_valid;
6112   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6113
6114   /* send it... */
6115   S (mp);
6116
6117   /* Wait for a reply, return the good/bad news... */
6118   W (ret);
6119   return ret;
6120 }
6121
6122 static int
6123 api_sw_interface_set_rx_placement (vat_main_t * vam)
6124 {
6125   unformat_input_t *i = vam->input;
6126   vl_api_sw_interface_set_rx_placement_t *mp;
6127   u32 sw_if_index;
6128   u8 sw_if_index_set = 0;
6129   int ret;
6130   u8 is_main = 0;
6131   u32 queue_id, thread_index;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "queue %d", &queue_id))
6137         ;
6138       else if (unformat (i, "main"))
6139         is_main = 1;
6140       else if (unformat (i, "worker %d", &thread_index))
6141         ;
6142       else
6143         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6144         sw_if_index_set = 1;
6145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6146         sw_if_index_set = 1;
6147       else
6148         break;
6149     }
6150
6151   if (sw_if_index_set == 0)
6152     {
6153       errmsg ("missing interface name or sw_if_index");
6154       return -99;
6155     }
6156
6157   if (is_main)
6158     thread_index = 0;
6159   /* Construct the API message */
6160   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6161   mp->sw_if_index = ntohl (sw_if_index);
6162   mp->worker_id = ntohl (thread_index);
6163   mp->queue_id = ntohl (queue_id);
6164   mp->is_main = is_main;
6165
6166   /* send it... */
6167   S (mp);
6168   /* Wait for a reply, return the good/bad news... */
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static void vl_api_sw_interface_rx_placement_details_t_handler
6174   (vl_api_sw_interface_rx_placement_details_t * mp)
6175 {
6176   vat_main_t *vam = &vat_main;
6177   u32 worker_id = ntohl (mp->worker_id);
6178
6179   print (vam->ofp,
6180          "\n%-11d %-11s %-6d %-5d %-9s",
6181          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6182          worker_id, ntohl (mp->queue_id),
6183          (mp->mode ==
6184           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6185 }
6186
6187 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6188   (vl_api_sw_interface_rx_placement_details_t * mp)
6189 {
6190   vat_main_t *vam = &vat_main;
6191   vat_json_node_t *node = NULL;
6192
6193   if (VAT_JSON_ARRAY != vam->json_tree.type)
6194     {
6195       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6196       vat_json_init_array (&vam->json_tree);
6197     }
6198   node = vat_json_array_add (&vam->json_tree);
6199
6200   vat_json_init_object (node);
6201   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6202   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6203   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6204   vat_json_object_add_uint (node, "mode", mp->mode);
6205 }
6206
6207 static int
6208 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6209 {
6210   unformat_input_t *i = vam->input;
6211   vl_api_sw_interface_rx_placement_dump_t *mp;
6212   vl_api_control_ping_t *mp_ping;
6213   int ret;
6214   u32 sw_if_index;
6215   u8 sw_if_index_set = 0;
6216
6217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6218     {
6219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6220         sw_if_index_set++;
6221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6222         sw_if_index_set++;
6223       else
6224         break;
6225     }
6226
6227   print (vam->ofp,
6228          "\n%-11s %-11s %-6s %-5s %-4s",
6229          "sw_if_index", "main/worker", "thread", "queue", "mode");
6230
6231   /* Dump Interface rx placement */
6232   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6233
6234   if (sw_if_index_set)
6235     mp->sw_if_index = htonl (sw_if_index);
6236   else
6237     mp->sw_if_index = ~0;
6238
6239   S (mp);
6240
6241   /* Use a control ping for synchronization */
6242   MPING (CONTROL_PING, mp_ping);
6243   S (mp_ping);
6244
6245   W (ret);
6246   return ret;
6247 }
6248
6249 static int
6250 api_sw_interface_clear_stats (vat_main_t * vam)
6251 {
6252   unformat_input_t *i = vam->input;
6253   vl_api_sw_interface_clear_stats_t *mp;
6254   u32 sw_if_index;
6255   u8 sw_if_index_set = 0;
6256   int ret;
6257
6258   /* Parse args required to build the message */
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6264         sw_if_index_set = 1;
6265       else
6266         break;
6267     }
6268
6269   /* Construct the API message */
6270   M (SW_INTERFACE_CLEAR_STATS, mp);
6271
6272   if (sw_if_index_set == 1)
6273     mp->sw_if_index = ntohl (sw_if_index);
6274   else
6275     mp->sw_if_index = ~0;
6276
6277   /* send it... */
6278   S (mp);
6279
6280   /* Wait for a reply, return the good/bad news... */
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static int
6286 api_sw_interface_add_del_address (vat_main_t * vam)
6287 {
6288   unformat_input_t *i = vam->input;
6289   vl_api_sw_interface_add_del_address_t *mp;
6290   u32 sw_if_index;
6291   u8 sw_if_index_set = 0;
6292   u8 is_add = 1, del_all = 0;
6293   u32 address_length = 0;
6294   u8 v4_address_set = 0;
6295   u8 v6_address_set = 0;
6296   ip4_address_t v4address;
6297   ip6_address_t v6address;
6298   int ret;
6299
6300   /* Parse args required to build the message */
6301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6302     {
6303       if (unformat (i, "del-all"))
6304         del_all = 1;
6305       else if (unformat (i, "del"))
6306         is_add = 0;
6307       else
6308         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6309         sw_if_index_set = 1;
6310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6311         sw_if_index_set = 1;
6312       else if (unformat (i, "%U/%d",
6313                          unformat_ip4_address, &v4address, &address_length))
6314         v4_address_set = 1;
6315       else if (unformat (i, "%U/%d",
6316                          unformat_ip6_address, &v6address, &address_length))
6317         v6_address_set = 1;
6318       else
6319         break;
6320     }
6321
6322   if (sw_if_index_set == 0)
6323     {
6324       errmsg ("missing interface name or sw_if_index");
6325       return -99;
6326     }
6327   if (v4_address_set && v6_address_set)
6328     {
6329       errmsg ("both v4 and v6 addresses set");
6330       return -99;
6331     }
6332   if (!v4_address_set && !v6_address_set && !del_all)
6333     {
6334       errmsg ("no addresses set");
6335       return -99;
6336     }
6337
6338   /* Construct the API message */
6339   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6340
6341   mp->sw_if_index = ntohl (sw_if_index);
6342   mp->is_add = is_add;
6343   mp->del_all = del_all;
6344   if (v6_address_set)
6345     {
6346       mp->is_ipv6 = 1;
6347       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6348     }
6349   else
6350     {
6351       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6352     }
6353   mp->address_length = address_length;
6354
6355   /* send it... */
6356   S (mp);
6357
6358   /* Wait for a reply, return good/bad news  */
6359   W (ret);
6360   return ret;
6361 }
6362
6363 static int
6364 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6365 {
6366   unformat_input_t *i = vam->input;
6367   vl_api_sw_interface_set_mpls_enable_t *mp;
6368   u32 sw_if_index;
6369   u8 sw_if_index_set = 0;
6370   u8 enable = 1;
6371   int ret;
6372
6373   /* Parse args required to build the message */
6374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6375     {
6376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6377         sw_if_index_set = 1;
6378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6379         sw_if_index_set = 1;
6380       else if (unformat (i, "disable"))
6381         enable = 0;
6382       else if (unformat (i, "dis"))
6383         enable = 0;
6384       else
6385         break;
6386     }
6387
6388   if (sw_if_index_set == 0)
6389     {
6390       errmsg ("missing interface name or sw_if_index");
6391       return -99;
6392     }
6393
6394   /* Construct the API message */
6395   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6396
6397   mp->sw_if_index = ntohl (sw_if_index);
6398   mp->enable = enable;
6399
6400   /* send it... */
6401   S (mp);
6402
6403   /* Wait for a reply... */
6404   W (ret);
6405   return ret;
6406 }
6407
6408 static int
6409 api_sw_interface_set_table (vat_main_t * vam)
6410 {
6411   unformat_input_t *i = vam->input;
6412   vl_api_sw_interface_set_table_t *mp;
6413   u32 sw_if_index, vrf_id = 0;
6414   u8 sw_if_index_set = 0;
6415   u8 is_ipv6 = 0;
6416   int ret;
6417
6418   /* Parse args required to build the message */
6419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6420     {
6421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6422         sw_if_index_set = 1;
6423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6424         sw_if_index_set = 1;
6425       else if (unformat (i, "vrf %d", &vrf_id))
6426         ;
6427       else if (unformat (i, "ipv6"))
6428         is_ipv6 = 1;
6429       else
6430         break;
6431     }
6432
6433   if (sw_if_index_set == 0)
6434     {
6435       errmsg ("missing interface name or sw_if_index");
6436       return -99;
6437     }
6438
6439   /* Construct the API message */
6440   M (SW_INTERFACE_SET_TABLE, mp);
6441
6442   mp->sw_if_index = ntohl (sw_if_index);
6443   mp->is_ipv6 = is_ipv6;
6444   mp->vrf_id = ntohl (vrf_id);
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static void vl_api_sw_interface_get_table_reply_t_handler
6455   (vl_api_sw_interface_get_table_reply_t * mp)
6456 {
6457   vat_main_t *vam = &vat_main;
6458
6459   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6460
6461   vam->retval = ntohl (mp->retval);
6462   vam->result_ready = 1;
6463
6464 }
6465
6466 static void vl_api_sw_interface_get_table_reply_t_handler_json
6467   (vl_api_sw_interface_get_table_reply_t * mp)
6468 {
6469   vat_main_t *vam = &vat_main;
6470   vat_json_node_t node;
6471
6472   vat_json_init_object (&node);
6473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6474   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6475
6476   vat_json_print (vam->ofp, &node);
6477   vat_json_free (&node);
6478
6479   vam->retval = ntohl (mp->retval);
6480   vam->result_ready = 1;
6481 }
6482
6483 static int
6484 api_sw_interface_get_table (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_sw_interface_get_table_t *mp;
6488   u32 sw_if_index;
6489   u8 sw_if_index_set = 0;
6490   u8 is_ipv6 = 0;
6491   int ret;
6492
6493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6494     {
6495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6496         sw_if_index_set = 1;
6497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6498         sw_if_index_set = 1;
6499       else if (unformat (i, "ipv6"))
6500         is_ipv6 = 1;
6501       else
6502         break;
6503     }
6504
6505   if (sw_if_index_set == 0)
6506     {
6507       errmsg ("missing interface name or sw_if_index");
6508       return -99;
6509     }
6510
6511   M (SW_INTERFACE_GET_TABLE, mp);
6512   mp->sw_if_index = htonl (sw_if_index);
6513   mp->is_ipv6 = is_ipv6;
6514
6515   S (mp);
6516   W (ret);
6517   return ret;
6518 }
6519
6520 static int
6521 api_sw_interface_set_vpath (vat_main_t * vam)
6522 {
6523   unformat_input_t *i = vam->input;
6524   vl_api_sw_interface_set_vpath_t *mp;
6525   u32 sw_if_index = 0;
6526   u8 sw_if_index_set = 0;
6527   u8 is_enable = 0;
6528   int ret;
6529
6530   /* Parse args required to build the message */
6531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6532     {
6533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6534         sw_if_index_set = 1;
6535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6536         sw_if_index_set = 1;
6537       else if (unformat (i, "enable"))
6538         is_enable = 1;
6539       else if (unformat (i, "disable"))
6540         is_enable = 0;
6541       else
6542         break;
6543     }
6544
6545   if (sw_if_index_set == 0)
6546     {
6547       errmsg ("missing interface name or sw_if_index");
6548       return -99;
6549     }
6550
6551   /* Construct the API message */
6552   M (SW_INTERFACE_SET_VPATH, mp);
6553
6554   mp->sw_if_index = ntohl (sw_if_index);
6555   mp->enable = is_enable;
6556
6557   /* send it... */
6558   S (mp);
6559
6560   /* Wait for a reply... */
6561   W (ret);
6562   return ret;
6563 }
6564
6565 static int
6566 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6567 {
6568   unformat_input_t *i = vam->input;
6569   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6570   u32 sw_if_index = 0;
6571   u8 sw_if_index_set = 0;
6572   u8 is_enable = 1;
6573   u8 is_ipv6 = 0;
6574   int ret;
6575
6576   /* Parse args required to build the message */
6577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6578     {
6579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6580         sw_if_index_set = 1;
6581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "enable"))
6584         is_enable = 1;
6585       else if (unformat (i, "disable"))
6586         is_enable = 0;
6587       else if (unformat (i, "ip4"))
6588         is_ipv6 = 0;
6589       else if (unformat (i, "ip6"))
6590         is_ipv6 = 1;
6591       else
6592         break;
6593     }
6594
6595   if (sw_if_index_set == 0)
6596     {
6597       errmsg ("missing interface name or sw_if_index");
6598       return -99;
6599     }
6600
6601   /* Construct the API message */
6602   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6603
6604   mp->sw_if_index = ntohl (sw_if_index);
6605   mp->enable = is_enable;
6606   mp->is_ipv6 = is_ipv6;
6607
6608   /* send it... */
6609   S (mp);
6610
6611   /* Wait for a reply... */
6612   W (ret);
6613   return ret;
6614 }
6615
6616 static int
6617 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6618 {
6619   unformat_input_t *i = vam->input;
6620   vl_api_sw_interface_set_geneve_bypass_t *mp;
6621   u32 sw_if_index = 0;
6622   u8 sw_if_index_set = 0;
6623   u8 is_enable = 1;
6624   u8 is_ipv6 = 0;
6625   int ret;
6626
6627   /* Parse args required to build the message */
6628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6629     {
6630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6631         sw_if_index_set = 1;
6632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6633         sw_if_index_set = 1;
6634       else if (unformat (i, "enable"))
6635         is_enable = 1;
6636       else if (unformat (i, "disable"))
6637         is_enable = 0;
6638       else if (unformat (i, "ip4"))
6639         is_ipv6 = 0;
6640       else if (unformat (i, "ip6"))
6641         is_ipv6 = 1;
6642       else
6643         break;
6644     }
6645
6646   if (sw_if_index_set == 0)
6647     {
6648       errmsg ("missing interface name or sw_if_index");
6649       return -99;
6650     }
6651
6652   /* Construct the API message */
6653   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6654
6655   mp->sw_if_index = ntohl (sw_if_index);
6656   mp->enable = is_enable;
6657   mp->is_ipv6 = is_ipv6;
6658
6659   /* send it... */
6660   S (mp);
6661
6662   /* Wait for a reply... */
6663   W (ret);
6664   return ret;
6665 }
6666
6667 static int
6668 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6669 {
6670   unformat_input_t *i = vam->input;
6671   vl_api_sw_interface_set_l2_xconnect_t *mp;
6672   u32 rx_sw_if_index;
6673   u8 rx_sw_if_index_set = 0;
6674   u32 tx_sw_if_index;
6675   u8 tx_sw_if_index_set = 0;
6676   u8 enable = 1;
6677   int ret;
6678
6679   /* Parse args required to build the message */
6680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6681     {
6682       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6683         rx_sw_if_index_set = 1;
6684       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6685         tx_sw_if_index_set = 1;
6686       else if (unformat (i, "rx"))
6687         {
6688           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689             {
6690               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6691                             &rx_sw_if_index))
6692                 rx_sw_if_index_set = 1;
6693             }
6694           else
6695             break;
6696         }
6697       else if (unformat (i, "tx"))
6698         {
6699           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6700             {
6701               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6702                             &tx_sw_if_index))
6703                 tx_sw_if_index_set = 1;
6704             }
6705           else
6706             break;
6707         }
6708       else if (unformat (i, "enable"))
6709         enable = 1;
6710       else if (unformat (i, "disable"))
6711         enable = 0;
6712       else
6713         break;
6714     }
6715
6716   if (rx_sw_if_index_set == 0)
6717     {
6718       errmsg ("missing rx interface name or rx_sw_if_index");
6719       return -99;
6720     }
6721
6722   if (enable && (tx_sw_if_index_set == 0))
6723     {
6724       errmsg ("missing tx interface name or tx_sw_if_index");
6725       return -99;
6726     }
6727
6728   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6729
6730   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6731   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6732   mp->enable = enable;
6733
6734   S (mp);
6735   W (ret);
6736   return ret;
6737 }
6738
6739 static int
6740 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6741 {
6742   unformat_input_t *i = vam->input;
6743   vl_api_sw_interface_set_l2_bridge_t *mp;
6744   vl_api_l2_port_type_t port_type;
6745   u32 rx_sw_if_index;
6746   u8 rx_sw_if_index_set = 0;
6747   u32 bd_id;
6748   u8 bd_id_set = 0;
6749   u32 shg = 0;
6750   u8 enable = 1;
6751   int ret;
6752
6753   port_type = L2_API_PORT_TYPE_NORMAL;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6759         rx_sw_if_index_set = 1;
6760       else if (unformat (i, "bd_id %d", &bd_id))
6761         bd_id_set = 1;
6762       else
6763         if (unformat
6764             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6765         rx_sw_if_index_set = 1;
6766       else if (unformat (i, "shg %d", &shg))
6767         ;
6768       else if (unformat (i, "bvi"))
6769         port_type = L2_API_PORT_TYPE_BVI;
6770       else if (unformat (i, "uu-fwd"))
6771         port_type = L2_API_PORT_TYPE_UU_FWD;
6772       else if (unformat (i, "enable"))
6773         enable = 1;
6774       else if (unformat (i, "disable"))
6775         enable = 0;
6776       else
6777         break;
6778     }
6779
6780   if (rx_sw_if_index_set == 0)
6781     {
6782       errmsg ("missing rx interface name or sw_if_index");
6783       return -99;
6784     }
6785
6786   if (enable && (bd_id_set == 0))
6787     {
6788       errmsg ("missing bridge domain");
6789       return -99;
6790     }
6791
6792   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6793
6794   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6795   mp->bd_id = ntohl (bd_id);
6796   mp->shg = (u8) shg;
6797   mp->port_type = ntohl (port_type);
6798   mp->enable = enable;
6799
6800   S (mp);
6801   W (ret);
6802   return ret;
6803 }
6804
6805 static int
6806 api_bridge_domain_dump (vat_main_t * vam)
6807 {
6808   unformat_input_t *i = vam->input;
6809   vl_api_bridge_domain_dump_t *mp;
6810   vl_api_control_ping_t *mp_ping;
6811   u32 bd_id = ~0;
6812   int ret;
6813
6814   /* Parse args required to build the message */
6815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6816     {
6817       if (unformat (i, "bd_id %d", &bd_id))
6818         ;
6819       else
6820         break;
6821     }
6822
6823   M (BRIDGE_DOMAIN_DUMP, mp);
6824   mp->bd_id = ntohl (bd_id);
6825   S (mp);
6826
6827   /* Use a control ping for synchronization */
6828   MPING (CONTROL_PING, mp_ping);
6829   S (mp_ping);
6830
6831   W (ret);
6832   return ret;
6833 }
6834
6835 static int
6836 api_bridge_domain_add_del (vat_main_t * vam)
6837 {
6838   unformat_input_t *i = vam->input;
6839   vl_api_bridge_domain_add_del_t *mp;
6840   u32 bd_id = ~0;
6841   u8 is_add = 1;
6842   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6843   u8 *bd_tag = NULL;
6844   u32 mac_age = 0;
6845   int ret;
6846
6847   /* Parse args required to build the message */
6848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6849     {
6850       if (unformat (i, "bd_id %d", &bd_id))
6851         ;
6852       else if (unformat (i, "flood %d", &flood))
6853         ;
6854       else if (unformat (i, "uu-flood %d", &uu_flood))
6855         ;
6856       else if (unformat (i, "forward %d", &forward))
6857         ;
6858       else if (unformat (i, "learn %d", &learn))
6859         ;
6860       else if (unformat (i, "arp-term %d", &arp_term))
6861         ;
6862       else if (unformat (i, "mac-age %d", &mac_age))
6863         ;
6864       else if (unformat (i, "bd-tag %s", &bd_tag))
6865         ;
6866       else if (unformat (i, "del"))
6867         {
6868           is_add = 0;
6869           flood = uu_flood = forward = learn = 0;
6870         }
6871       else
6872         break;
6873     }
6874
6875   if (bd_id == ~0)
6876     {
6877       errmsg ("missing bridge domain");
6878       ret = -99;
6879       goto done;
6880     }
6881
6882   if (mac_age > 255)
6883     {
6884       errmsg ("mac age must be less than 256 ");
6885       ret = -99;
6886       goto done;
6887     }
6888
6889   if ((bd_tag) && (vec_len (bd_tag) > 63))
6890     {
6891       errmsg ("bd-tag cannot be longer than 63");
6892       ret = -99;
6893       goto done;
6894     }
6895
6896   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6897
6898   mp->bd_id = ntohl (bd_id);
6899   mp->flood = flood;
6900   mp->uu_flood = uu_flood;
6901   mp->forward = forward;
6902   mp->learn = learn;
6903   mp->arp_term = arp_term;
6904   mp->is_add = is_add;
6905   mp->mac_age = (u8) mac_age;
6906   if (bd_tag)
6907     {
6908       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6909       mp->bd_tag[vec_len (bd_tag)] = 0;
6910     }
6911   S (mp);
6912   W (ret);
6913
6914 done:
6915   vec_free (bd_tag);
6916   return ret;
6917 }
6918
6919 static int
6920 api_l2fib_flush_bd (vat_main_t * vam)
6921 {
6922   unformat_input_t *i = vam->input;
6923   vl_api_l2fib_flush_bd_t *mp;
6924   u32 bd_id = ~0;
6925   int ret;
6926
6927   /* Parse args required to build the message */
6928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6929     {
6930       if (unformat (i, "bd_id %d", &bd_id));
6931       else
6932         break;
6933     }
6934
6935   if (bd_id == ~0)
6936     {
6937       errmsg ("missing bridge domain");
6938       return -99;
6939     }
6940
6941   M (L2FIB_FLUSH_BD, mp);
6942
6943   mp->bd_id = htonl (bd_id);
6944
6945   S (mp);
6946   W (ret);
6947   return ret;
6948 }
6949
6950 static int
6951 api_l2fib_flush_int (vat_main_t * vam)
6952 {
6953   unformat_input_t *i = vam->input;
6954   vl_api_l2fib_flush_int_t *mp;
6955   u32 sw_if_index = ~0;
6956   int ret;
6957
6958   /* Parse args required to build the message */
6959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960     {
6961       if (unformat (i, "sw_if_index %d", &sw_if_index));
6962       else
6963         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6964       else
6965         break;
6966     }
6967
6968   if (sw_if_index == ~0)
6969     {
6970       errmsg ("missing interface name or sw_if_index");
6971       return -99;
6972     }
6973
6974   M (L2FIB_FLUSH_INT, mp);
6975
6976   mp->sw_if_index = ntohl (sw_if_index);
6977
6978   S (mp);
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_l2fib_add_del (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_l2fib_add_del_t *mp;
6988   f64 timeout;
6989   u8 mac[6] = { 0 };
6990   u8 mac_set = 0;
6991   u32 bd_id;
6992   u8 bd_id_set = 0;
6993   u32 sw_if_index = 0;
6994   u8 sw_if_index_set = 0;
6995   u8 is_add = 1;
6996   u8 static_mac = 0;
6997   u8 filter_mac = 0;
6998   u8 bvi_mac = 0;
6999   int count = 1;
7000   f64 before = 0;
7001   int j;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7007         mac_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7011         sw_if_index_set = 1;
7012       else if (unformat (i, "sw_if"))
7013         {
7014           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7015             {
7016               if (unformat
7017                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7018                 sw_if_index_set = 1;
7019             }
7020           else
7021             break;
7022         }
7023       else if (unformat (i, "static"))
7024         static_mac = 1;
7025       else if (unformat (i, "filter"))
7026         {
7027           filter_mac = 1;
7028           static_mac = 1;
7029         }
7030       else if (unformat (i, "bvi"))
7031         {
7032           bvi_mac = 1;
7033           static_mac = 1;
7034         }
7035       else if (unformat (i, "del"))
7036         is_add = 0;
7037       else if (unformat (i, "count %d", &count))
7038         ;
7039       else
7040         break;
7041     }
7042
7043   if (mac_set == 0)
7044     {
7045       errmsg ("missing mac address");
7046       return -99;
7047     }
7048
7049   if (bd_id_set == 0)
7050     {
7051       errmsg ("missing bridge domain");
7052       return -99;
7053     }
7054
7055   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7056     {
7057       errmsg ("missing interface name or sw_if_index");
7058       return -99;
7059     }
7060
7061   if (count > 1)
7062     {
7063       /* Turn on async mode */
7064       vam->async_mode = 1;
7065       vam->async_errors = 0;
7066       before = vat_time_now (vam);
7067     }
7068
7069   for (j = 0; j < count; j++)
7070     {
7071       M (L2FIB_ADD_DEL, mp);
7072
7073       clib_memcpy (mp->mac, mac, 6);
7074       mp->bd_id = ntohl (bd_id);
7075       mp->is_add = is_add;
7076       mp->sw_if_index = ntohl (sw_if_index);
7077
7078       if (is_add)
7079         {
7080           mp->static_mac = static_mac;
7081           mp->filter_mac = filter_mac;
7082           mp->bvi_mac = bvi_mac;
7083         }
7084       increment_mac_address (mac);
7085       /* send it... */
7086       S (mp);
7087     }
7088
7089   if (count > 1)
7090     {
7091       vl_api_control_ping_t *mp_ping;
7092       f64 after;
7093
7094       /* Shut off async mode */
7095       vam->async_mode = 0;
7096
7097       MPING (CONTROL_PING, mp_ping);
7098       S (mp_ping);
7099
7100       timeout = vat_time_now (vam) + 1.0;
7101       while (vat_time_now (vam) < timeout)
7102         if (vam->result_ready == 1)
7103           goto out;
7104       vam->retval = -99;
7105
7106     out:
7107       if (vam->retval == -99)
7108         errmsg ("timeout");
7109
7110       if (vam->async_errors > 0)
7111         {
7112           errmsg ("%d asynchronous errors", vam->async_errors);
7113           vam->retval = -98;
7114         }
7115       vam->async_errors = 0;
7116       after = vat_time_now (vam);
7117
7118       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7119              count, after - before, count / (after - before));
7120     }
7121   else
7122     {
7123       int ret;
7124
7125       /* Wait for a reply... */
7126       W (ret);
7127       return ret;
7128     }
7129   /* Return the good/bad news */
7130   return (vam->retval);
7131 }
7132
7133 static int
7134 api_bridge_domain_set_mac_age (vat_main_t * vam)
7135 {
7136   unformat_input_t *i = vam->input;
7137   vl_api_bridge_domain_set_mac_age_t *mp;
7138   u32 bd_id = ~0;
7139   u32 mac_age = 0;
7140   int ret;
7141
7142   /* Parse args required to build the message */
7143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7144     {
7145       if (unformat (i, "bd_id %d", &bd_id));
7146       else if (unformat (i, "mac-age %d", &mac_age));
7147       else
7148         break;
7149     }
7150
7151   if (bd_id == ~0)
7152     {
7153       errmsg ("missing bridge domain");
7154       return -99;
7155     }
7156
7157   if (mac_age > 255)
7158     {
7159       errmsg ("mac age must be less than 256 ");
7160       return -99;
7161     }
7162
7163   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7164
7165   mp->bd_id = htonl (bd_id);
7166   mp->mac_age = (u8) mac_age;
7167
7168   S (mp);
7169   W (ret);
7170   return ret;
7171 }
7172
7173 static int
7174 api_l2_flags (vat_main_t * vam)
7175 {
7176   unformat_input_t *i = vam->input;
7177   vl_api_l2_flags_t *mp;
7178   u32 sw_if_index;
7179   u32 flags = 0;
7180   u8 sw_if_index_set = 0;
7181   u8 is_set = 0;
7182   int ret;
7183
7184   /* Parse args required to build the message */
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "sw_if_index %d", &sw_if_index))
7188         sw_if_index_set = 1;
7189       else if (unformat (i, "sw_if"))
7190         {
7191           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7192             {
7193               if (unformat
7194                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7195                 sw_if_index_set = 1;
7196             }
7197           else
7198             break;
7199         }
7200       else if (unformat (i, "learn"))
7201         flags |= L2_LEARN;
7202       else if (unformat (i, "forward"))
7203         flags |= L2_FWD;
7204       else if (unformat (i, "flood"))
7205         flags |= L2_FLOOD;
7206       else if (unformat (i, "uu-flood"))
7207         flags |= L2_UU_FLOOD;
7208       else if (unformat (i, "arp-term"))
7209         flags |= L2_ARP_TERM;
7210       else if (unformat (i, "off"))
7211         is_set = 0;
7212       else if (unformat (i, "disable"))
7213         is_set = 0;
7214       else
7215         break;
7216     }
7217
7218   if (sw_if_index_set == 0)
7219     {
7220       errmsg ("missing interface name or sw_if_index");
7221       return -99;
7222     }
7223
7224   M (L2_FLAGS, mp);
7225
7226   mp->sw_if_index = ntohl (sw_if_index);
7227   mp->feature_bitmap = ntohl (flags);
7228   mp->is_set = is_set;
7229
7230   S (mp);
7231   W (ret);
7232   return ret;
7233 }
7234
7235 static int
7236 api_bridge_flags (vat_main_t * vam)
7237 {
7238   unformat_input_t *i = vam->input;
7239   vl_api_bridge_flags_t *mp;
7240   u32 bd_id;
7241   u8 bd_id_set = 0;
7242   u8 is_set = 1;
7243   bd_flags_t flags = 0;
7244   int ret;
7245
7246   /* Parse args required to build the message */
7247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7248     {
7249       if (unformat (i, "bd_id %d", &bd_id))
7250         bd_id_set = 1;
7251       else if (unformat (i, "learn"))
7252         flags |= BRIDGE_API_FLAG_LEARN;
7253       else if (unformat (i, "forward"))
7254         flags |= BRIDGE_API_FLAG_FWD;
7255       else if (unformat (i, "flood"))
7256         flags |= BRIDGE_API_FLAG_FLOOD;
7257       else if (unformat (i, "uu-flood"))
7258         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7259       else if (unformat (i, "arp-term"))
7260         flags |= BRIDGE_API_FLAG_ARP_TERM;
7261       else if (unformat (i, "off"))
7262         is_set = 0;
7263       else if (unformat (i, "disable"))
7264         is_set = 0;
7265       else
7266         break;
7267     }
7268
7269   if (bd_id_set == 0)
7270     {
7271       errmsg ("missing bridge domain");
7272       return -99;
7273     }
7274
7275   M (BRIDGE_FLAGS, mp);
7276
7277   mp->bd_id = ntohl (bd_id);
7278   mp->flags = ntohl (flags);
7279   mp->is_set = is_set;
7280
7281   S (mp);
7282   W (ret);
7283   return ret;
7284 }
7285
7286 static int
7287 api_bd_ip_mac_add_del (vat_main_t * vam)
7288 {
7289   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7290   vl_api_mac_address_t mac = { 0 };
7291   unformat_input_t *i = vam->input;
7292   vl_api_bd_ip_mac_add_del_t *mp;
7293   u32 bd_id;
7294   u8 is_add = 1;
7295   u8 bd_id_set = 0;
7296   u8 ip_set = 0;
7297   u8 mac_set = 0;
7298   int ret;
7299
7300
7301   /* Parse args required to build the message */
7302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7303     {
7304       if (unformat (i, "bd_id %d", &bd_id))
7305         {
7306           bd_id_set++;
7307         }
7308       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7309         {
7310           ip_set++;
7311         }
7312       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7313         {
7314           mac_set++;
7315         }
7316       else if (unformat (i, "del"))
7317         is_add = 0;
7318       else
7319         break;
7320     }
7321
7322   if (bd_id_set == 0)
7323     {
7324       errmsg ("missing bridge domain");
7325       return -99;
7326     }
7327   else if (ip_set == 0)
7328     {
7329       errmsg ("missing IP address");
7330       return -99;
7331     }
7332   else if (mac_set == 0)
7333     {
7334       errmsg ("missing MAC address");
7335       return -99;
7336     }
7337
7338   M (BD_IP_MAC_ADD_DEL, mp);
7339
7340   mp->bd_id = ntohl (bd_id);
7341   mp->is_add = is_add;
7342
7343   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7344   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7345
7346   S (mp);
7347   W (ret);
7348   return ret;
7349 }
7350
7351 static int
7352 api_bd_ip_mac_flush (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_bd_ip_mac_flush_t *mp;
7356   u32 bd_id;
7357   u8 bd_id_set = 0;
7358   int ret;
7359
7360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7361     {
7362       if (unformat (i, "bd_id %d", &bd_id))
7363         {
7364           bd_id_set++;
7365         }
7366       else
7367         break;
7368     }
7369
7370   if (bd_id_set == 0)
7371     {
7372       errmsg ("missing bridge domain");
7373       return -99;
7374     }
7375
7376   M (BD_IP_MAC_FLUSH, mp);
7377
7378   mp->bd_id = ntohl (bd_id);
7379
7380   S (mp);
7381   W (ret);
7382   return ret;
7383 }
7384
7385 static void vl_api_bd_ip_mac_details_t_handler
7386   (vl_api_bd_ip_mac_details_t * mp)
7387 {
7388   vat_main_t *vam = &vat_main;
7389   u8 *ip = 0;
7390
7391   if (!mp->is_ipv6)
7392     ip =
7393       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7394   else
7395     ip =
7396       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7397
7398   print (vam->ofp,
7399          "\n%-5d %-7s %-20U %-30s",
7400          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7401          format_ethernet_address, mp->mac_address, ip);
7402
7403   vec_free (ip);
7404 }
7405
7406 static void vl_api_bd_ip_mac_details_t_handler_json
7407   (vl_api_bd_ip_mac_details_t * mp)
7408 {
7409   vat_main_t *vam = &vat_main;
7410   vat_json_node_t *node = NULL;
7411
7412   if (VAT_JSON_ARRAY != vam->json_tree.type)
7413     {
7414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7415       vat_json_init_array (&vam->json_tree);
7416     }
7417   node = vat_json_array_add (&vam->json_tree);
7418
7419   vat_json_init_object (node);
7420   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7421   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7422   vat_json_object_add_string_copy (node, "mac_address",
7423                                    format (0, "%U", format_ethernet_address,
7424                                            &mp->mac_address));
7425   u8 *ip = 0;
7426
7427   if (!mp->is_ipv6)
7428     ip =
7429       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7430   else
7431     ip =
7432       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7433   vat_json_object_add_string_copy (node, "ip_address", ip);
7434   vec_free (ip);
7435 }
7436
7437 static int
7438 api_bd_ip_mac_dump (vat_main_t * vam)
7439 {
7440   unformat_input_t *i = vam->input;
7441   vl_api_bd_ip_mac_dump_t *mp;
7442   vl_api_control_ping_t *mp_ping;
7443   int ret;
7444   u32 bd_id;
7445   u8 bd_id_set = 0;
7446
7447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7448     {
7449       if (unformat (i, "bd_id %d", &bd_id))
7450         {
7451           bd_id_set++;
7452         }
7453       else
7454         break;
7455     }
7456
7457   print (vam->ofp,
7458          "\n%-5s %-7s %-20s %-30s",
7459          "bd_id", "is_ipv6", "mac_address", "ip_address");
7460
7461   /* Dump Bridge Domain Ip to Mac entries */
7462   M (BD_IP_MAC_DUMP, mp);
7463
7464   if (bd_id_set)
7465     mp->bd_id = htonl (bd_id);
7466   else
7467     mp->bd_id = ~0;
7468
7469   S (mp);
7470
7471   /* Use a control ping for synchronization */
7472   MPING (CONTROL_PING, mp_ping);
7473   S (mp_ping);
7474
7475   W (ret);
7476   return ret;
7477 }
7478
7479 static int
7480 api_tap_create_v2 (vat_main_t * vam)
7481 {
7482   unformat_input_t *i = vam->input;
7483   vl_api_tap_create_v2_t *mp;
7484   u8 mac_address[6];
7485   u8 random_mac = 1;
7486   u32 id = ~0;
7487   u8 *host_if_name = 0;
7488   u8 *host_ns = 0;
7489   u8 host_mac_addr[6];
7490   u8 host_mac_addr_set = 0;
7491   u8 *host_bridge = 0;
7492   ip4_address_t host_ip4_addr;
7493   ip4_address_t host_ip4_gw;
7494   u8 host_ip4_gw_set = 0;
7495   u32 host_ip4_prefix_len = 0;
7496   ip6_address_t host_ip6_addr;
7497   ip6_address_t host_ip6_gw;
7498   u8 host_ip6_gw_set = 0;
7499   u32 host_ip6_prefix_len = 0;
7500   int ret;
7501   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7502
7503   clib_memset (mac_address, 0, sizeof (mac_address));
7504
7505   /* Parse args required to build the message */
7506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7507     {
7508       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7509         {
7510           random_mac = 0;
7511         }
7512       else if (unformat (i, "id %u", &id))
7513         ;
7514       else if (unformat (i, "host-if-name %s", &host_if_name))
7515         ;
7516       else if (unformat (i, "host-ns %s", &host_ns))
7517         ;
7518       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7519                          host_mac_addr))
7520         host_mac_addr_set = 1;
7521       else if (unformat (i, "host-bridge %s", &host_bridge))
7522         ;
7523       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7524                          &host_ip4_addr, &host_ip4_prefix_len))
7525         ;
7526       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7527                          &host_ip6_addr, &host_ip6_prefix_len))
7528         ;
7529       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7530                          &host_ip4_gw))
7531         host_ip4_gw_set = 1;
7532       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7533                          &host_ip6_gw))
7534         host_ip6_gw_set = 1;
7535       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7536         ;
7537       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7538         ;
7539       else
7540         break;
7541     }
7542
7543   if (vec_len (host_if_name) > 63)
7544     {
7545       errmsg ("tap name too long. ");
7546       return -99;
7547     }
7548   if (vec_len (host_ns) > 63)
7549     {
7550       errmsg ("host name space too long. ");
7551       return -99;
7552     }
7553   if (vec_len (host_bridge) > 63)
7554     {
7555       errmsg ("host bridge name too long. ");
7556       return -99;
7557     }
7558   if (host_ip4_prefix_len > 32)
7559     {
7560       errmsg ("host ip4 prefix length not valid. ");
7561       return -99;
7562     }
7563   if (host_ip6_prefix_len > 128)
7564     {
7565       errmsg ("host ip6 prefix length not valid. ");
7566       return -99;
7567     }
7568   if (!is_pow2 (rx_ring_sz))
7569     {
7570       errmsg ("rx ring size must be power of 2. ");
7571       return -99;
7572     }
7573   if (rx_ring_sz > 32768)
7574     {
7575       errmsg ("rx ring size must be 32768 or lower. ");
7576       return -99;
7577     }
7578   if (!is_pow2 (tx_ring_sz))
7579     {
7580       errmsg ("tx ring size must be power of 2. ");
7581       return -99;
7582     }
7583   if (tx_ring_sz > 32768)
7584     {
7585       errmsg ("tx ring size must be 32768 or lower. ");
7586       return -99;
7587     }
7588
7589   /* Construct the API message */
7590   M (TAP_CREATE_V2, mp);
7591
7592   mp->use_random_mac = random_mac;
7593
7594   mp->id = ntohl (id);
7595   mp->host_namespace_set = host_ns != 0;
7596   mp->host_bridge_set = host_bridge != 0;
7597   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7598   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7599   mp->rx_ring_sz = ntohs (rx_ring_sz);
7600   mp->tx_ring_sz = ntohs (tx_ring_sz);
7601
7602   if (random_mac == 0)
7603     clib_memcpy (mp->mac_address, mac_address, 6);
7604   if (host_mac_addr_set)
7605     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7606   if (host_if_name)
7607     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7608   if (host_ns)
7609     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7610   if (host_bridge)
7611     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7612   if (host_ip4_prefix_len)
7613     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7614   if (host_ip6_prefix_len)
7615     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7616   if (host_ip4_gw_set)
7617     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7618   if (host_ip6_gw_set)
7619     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7620
7621   vec_free (host_ns);
7622   vec_free (host_if_name);
7623   vec_free (host_bridge);
7624
7625   /* send it... */
7626   S (mp);
7627
7628   /* Wait for a reply... */
7629   W (ret);
7630   return ret;
7631 }
7632
7633 static int
7634 api_tap_delete_v2 (vat_main_t * vam)
7635 {
7636   unformat_input_t *i = vam->input;
7637   vl_api_tap_delete_v2_t *mp;
7638   u32 sw_if_index = ~0;
7639   u8 sw_if_index_set = 0;
7640   int ret;
7641
7642   /* Parse args required to build the message */
7643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7644     {
7645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7646         sw_if_index_set = 1;
7647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7648         sw_if_index_set = 1;
7649       else
7650         break;
7651     }
7652
7653   if (sw_if_index_set == 0)
7654     {
7655       errmsg ("missing vpp interface name. ");
7656       return -99;
7657     }
7658
7659   /* Construct the API message */
7660   M (TAP_DELETE_V2, mp);
7661
7662   mp->sw_if_index = ntohl (sw_if_index);
7663
7664   /* send it... */
7665   S (mp);
7666
7667   /* Wait for a reply... */
7668   W (ret);
7669   return ret;
7670 }
7671
7672 uword
7673 unformat_pci_addr (unformat_input_t * input, va_list * args)
7674 {
7675   struct pci_addr_t
7676   {
7677     u16 domain;
7678     u8 bus;
7679     u8 slot:5;
7680     u8 function:3;
7681   } *addr;
7682   addr = va_arg (*args, struct pci_addr_t *);
7683   u32 x[4];
7684
7685   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7686     return 0;
7687
7688   addr->domain = x[0];
7689   addr->bus = x[1];
7690   addr->slot = x[2];
7691   addr->function = x[3];
7692
7693   return 1;
7694 }
7695
7696 static int
7697 api_virtio_pci_create (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_virtio_pci_create_t *mp;
7701   u8 mac_address[6];
7702   u8 random_mac = 1;
7703   u8 gso_enabled = 0;
7704   u32 pci_addr = 0;
7705   u64 features = (u64) ~ (0ULL);
7706   int ret;
7707
7708   clib_memset (mac_address, 0, sizeof (mac_address));
7709
7710   /* Parse args required to build the message */
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7714         {
7715           random_mac = 0;
7716         }
7717       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7718         ;
7719       else if (unformat (i, "features 0x%llx", &features))
7720         ;
7721       else if (unformat (i, "gso-enabled"))
7722         gso_enabled = 1;
7723       else
7724         break;
7725     }
7726
7727   if (pci_addr == 0)
7728     {
7729       errmsg ("pci address must be non zero. ");
7730       return -99;
7731     }
7732
7733   /* Construct the API message */
7734   M (VIRTIO_PCI_CREATE, mp);
7735
7736   mp->use_random_mac = random_mac;
7737
7738   mp->pci_addr = htonl (pci_addr);
7739   mp->features = clib_host_to_net_u64 (features);
7740   mp->gso_enabled = gso_enabled;
7741
7742   if (random_mac == 0)
7743     clib_memcpy (mp->mac_address, mac_address, 6);
7744
7745   /* send it... */
7746   S (mp);
7747
7748   /* Wait for a reply... */
7749   W (ret);
7750   return ret;
7751 }
7752
7753 static int
7754 api_virtio_pci_delete (vat_main_t * vam)
7755 {
7756   unformat_input_t *i = vam->input;
7757   vl_api_virtio_pci_delete_t *mp;
7758   u32 sw_if_index = ~0;
7759   u8 sw_if_index_set = 0;
7760   int ret;
7761
7762   /* Parse args required to build the message */
7763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7764     {
7765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7766         sw_if_index_set = 1;
7767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7768         sw_if_index_set = 1;
7769       else
7770         break;
7771     }
7772
7773   if (sw_if_index_set == 0)
7774     {
7775       errmsg ("missing vpp interface name. ");
7776       return -99;
7777     }
7778
7779   /* Construct the API message */
7780   M (VIRTIO_PCI_DELETE, mp);
7781
7782   mp->sw_if_index = htonl (sw_if_index);
7783
7784   /* send it... */
7785   S (mp);
7786
7787   /* Wait for a reply... */
7788   W (ret);
7789   return ret;
7790 }
7791
7792 static int
7793 api_bond_create (vat_main_t * vam)
7794 {
7795   unformat_input_t *i = vam->input;
7796   vl_api_bond_create_t *mp;
7797   u8 mac_address[6];
7798   u8 custom_mac = 0;
7799   int ret;
7800   u8 mode;
7801   u8 lb;
7802   u8 mode_is_set = 0;
7803   u32 id = ~0;
7804
7805   clib_memset (mac_address, 0, sizeof (mac_address));
7806   lb = BOND_LB_L2;
7807
7808   /* Parse args required to build the message */
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7812         mode_is_set = 1;
7813       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7814                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7815         ;
7816       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7817                          mac_address))
7818         custom_mac = 1;
7819       else if (unformat (i, "id %u", &id))
7820         ;
7821       else
7822         break;
7823     }
7824
7825   if (mode_is_set == 0)
7826     {
7827       errmsg ("Missing bond mode. ");
7828       return -99;
7829     }
7830
7831   /* Construct the API message */
7832   M (BOND_CREATE, mp);
7833
7834   mp->use_custom_mac = custom_mac;
7835
7836   mp->mode = mode;
7837   mp->lb = lb;
7838   mp->id = htonl (id);
7839
7840   if (custom_mac)
7841     clib_memcpy (mp->mac_address, mac_address, 6);
7842
7843   /* send it... */
7844   S (mp);
7845
7846   /* Wait for a reply... */
7847   W (ret);
7848   return ret;
7849 }
7850
7851 static int
7852 api_bond_delete (vat_main_t * vam)
7853 {
7854   unformat_input_t *i = vam->input;
7855   vl_api_bond_delete_t *mp;
7856   u32 sw_if_index = ~0;
7857   u8 sw_if_index_set = 0;
7858   int ret;
7859
7860   /* Parse args required to build the message */
7861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7862     {
7863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7864         sw_if_index_set = 1;
7865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7866         sw_if_index_set = 1;
7867       else
7868         break;
7869     }
7870
7871   if (sw_if_index_set == 0)
7872     {
7873       errmsg ("missing vpp interface name. ");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (BOND_DELETE, mp);
7879
7880   mp->sw_if_index = ntohl (sw_if_index);
7881
7882   /* send it... */
7883   S (mp);
7884
7885   /* Wait for a reply... */
7886   W (ret);
7887   return ret;
7888 }
7889
7890 static int
7891 api_bond_enslave (vat_main_t * vam)
7892 {
7893   unformat_input_t *i = vam->input;
7894   vl_api_bond_enslave_t *mp;
7895   u32 bond_sw_if_index;
7896   int ret;
7897   u8 is_passive;
7898   u8 is_long_timeout;
7899   u32 bond_sw_if_index_is_set = 0;
7900   u32 sw_if_index;
7901   u8 sw_if_index_is_set = 0;
7902
7903   /* Parse args required to build the message */
7904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7905     {
7906       if (unformat (i, "sw_if_index %d", &sw_if_index))
7907         sw_if_index_is_set = 1;
7908       else if (unformat (i, "bond %u", &bond_sw_if_index))
7909         bond_sw_if_index_is_set = 1;
7910       else if (unformat (i, "passive %d", &is_passive))
7911         ;
7912       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7913         ;
7914       else
7915         break;
7916     }
7917
7918   if (bond_sw_if_index_is_set == 0)
7919     {
7920       errmsg ("Missing bond sw_if_index. ");
7921       return -99;
7922     }
7923   if (sw_if_index_is_set == 0)
7924     {
7925       errmsg ("Missing slave sw_if_index. ");
7926       return -99;
7927     }
7928
7929   /* Construct the API message */
7930   M (BOND_ENSLAVE, mp);
7931
7932   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7933   mp->sw_if_index = ntohl (sw_if_index);
7934   mp->is_long_timeout = is_long_timeout;
7935   mp->is_passive = is_passive;
7936
7937   /* send it... */
7938   S (mp);
7939
7940   /* Wait for a reply... */
7941   W (ret);
7942   return ret;
7943 }
7944
7945 static int
7946 api_bond_detach_slave (vat_main_t * vam)
7947 {
7948   unformat_input_t *i = vam->input;
7949   vl_api_bond_detach_slave_t *mp;
7950   u32 sw_if_index = ~0;
7951   u8 sw_if_index_set = 0;
7952   int ret;
7953
7954   /* Parse args required to build the message */
7955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7956     {
7957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7958         sw_if_index_set = 1;
7959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7960         sw_if_index_set = 1;
7961       else
7962         break;
7963     }
7964
7965   if (sw_if_index_set == 0)
7966     {
7967       errmsg ("missing vpp interface name. ");
7968       return -99;
7969     }
7970
7971   /* Construct the API message */
7972   M (BOND_DETACH_SLAVE, mp);
7973
7974   mp->sw_if_index = ntohl (sw_if_index);
7975
7976   /* send it... */
7977   S (mp);
7978
7979   /* Wait for a reply... */
7980   W (ret);
7981   return ret;
7982 }
7983
7984 static int
7985 api_ip_table_add_del (vat_main_t * vam)
7986 {
7987   unformat_input_t *i = vam->input;
7988   vl_api_ip_table_add_del_t *mp;
7989   u32 table_id = ~0;
7990   u8 is_ipv6 = 0;
7991   u8 is_add = 1;
7992   int ret = 0;
7993
7994   /* Parse args required to build the message */
7995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (i, "ipv6"))
7998         is_ipv6 = 1;
7999       else if (unformat (i, "del"))
8000         is_add = 0;
8001       else if (unformat (i, "add"))
8002         is_add = 1;
8003       else if (unformat (i, "table %d", &table_id))
8004         ;
8005       else
8006         {
8007           clib_warning ("parse error '%U'", format_unformat_error, i);
8008           return -99;
8009         }
8010     }
8011
8012   if (~0 == table_id)
8013     {
8014       errmsg ("missing table-ID");
8015       return -99;
8016     }
8017
8018   /* Construct the API message */
8019   M (IP_TABLE_ADD_DEL, mp);
8020
8021   mp->table.table_id = ntohl (table_id);
8022   mp->table.is_ip6 = is_ipv6;
8023   mp->is_add = is_add;
8024
8025   /* send it... */
8026   S (mp);
8027
8028   /* Wait for a reply... */
8029   W (ret);
8030
8031   return ret;
8032 }
8033
8034 uword
8035 unformat_fib_path (unformat_input_t * input, va_list * args)
8036 {
8037   vat_main_t *vam = va_arg (*args, vat_main_t *);
8038   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8039   u32 weight, preference;
8040   mpls_label_t out_label;
8041
8042   clib_memset (path, 0, sizeof (*path));
8043   path->weight = 1;
8044   path->sw_if_index = ~0;
8045   path->rpf_id = ~0;
8046   path->n_labels = 0;
8047
8048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8049     {
8050       if (unformat (input, "%U %U",
8051                     unformat_vl_api_ip4_address,
8052                     &path->nh.address.ip4,
8053                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8054         {
8055           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8056         }
8057       else if (unformat (input, "%U %U",
8058                          unformat_vl_api_ip6_address,
8059                          &path->nh.address.ip6,
8060                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8061         {
8062           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8063         }
8064       else if (unformat (input, "weight %u", &weight))
8065         {
8066           path->weight = weight;
8067         }
8068       else if (unformat (input, "preference %u", &preference))
8069         {
8070           path->preference = preference;
8071         }
8072       else if (unformat (input, "%U next-hop-table %d",
8073                          unformat_vl_api_ip4_address,
8074                          &path->nh.address.ip4, &path->table_id))
8075         {
8076           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8077         }
8078       else if (unformat (input, "%U next-hop-table %d",
8079                          unformat_vl_api_ip6_address,
8080                          &path->nh.address.ip6, &path->table_id))
8081         {
8082           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8083         }
8084       else if (unformat (input, "%U",
8085                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8086         {
8087           /*
8088            * the recursive next-hops are by default in the default table
8089            */
8090           path->table_id = 0;
8091           path->sw_if_index = ~0;
8092           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8093         }
8094       else if (unformat (input, "%U",
8095                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8096         {
8097           /*
8098            * the recursive next-hops are by default in the default table
8099            */
8100           path->table_id = 0;
8101           path->sw_if_index = ~0;
8102           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8103         }
8104       else if (unformat (input, "resolve-via-host"))
8105         {
8106           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8107         }
8108       else if (unformat (input, "resolve-via-attached"))
8109         {
8110           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8111         }
8112       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8113         {
8114           path->type = FIB_API_PATH_TYPE_LOCAL;
8115           path->sw_if_index = ~0;
8116           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8117         }
8118       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8119         {
8120           path->type = FIB_API_PATH_TYPE_LOCAL;
8121           path->sw_if_index = ~0;
8122           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8123         }
8124       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8125         ;
8126       else if (unformat (input, "via-label %d", &path->nh.via_label))
8127         {
8128           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8129           path->sw_if_index = ~0;
8130         }
8131       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8132         {
8133           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8134           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8135         }
8136       else if (unformat (input, "local"))
8137         {
8138           path->type = FIB_API_PATH_TYPE_LOCAL;
8139         }
8140       else if (unformat (input, "out-labels"))
8141         {
8142           while (unformat (input, "%d", &out_label))
8143             {
8144               path->label_stack[path->n_labels].label = out_label;
8145               path->label_stack[path->n_labels].is_uniform = 0;
8146               path->label_stack[path->n_labels].ttl = 64;
8147               path->n_labels++;
8148             }
8149         }
8150       else if (unformat (input, "via"))
8151         {
8152           /* new path, back up and return */
8153           unformat_put_input (input);
8154           unformat_put_input (input);
8155           unformat_put_input (input);
8156           unformat_put_input (input);
8157           break;
8158         }
8159       else
8160         {
8161           return (0);
8162         }
8163     }
8164
8165   path->proto = ntohl (path->proto);
8166   path->type = ntohl (path->type);
8167   path->flags = ntohl (path->flags);
8168   path->table_id = ntohl (path->table_id);
8169   path->sw_if_index = ntohl (path->sw_if_index);
8170
8171   return (1);
8172 }
8173
8174 static int
8175 api_ip_route_add_del (vat_main_t * vam)
8176 {
8177   unformat_input_t *i = vam->input;
8178   vl_api_ip_route_add_del_t *mp;
8179   u32 vrf_id = 0;
8180   u8 is_add = 1;
8181   u8 is_multipath = 0;
8182   u8 prefix_set = 0;
8183   u8 path_count = 0;
8184   vl_api_prefix_t pfx = { };
8185   vl_api_fib_path_t paths[8];
8186   int count = 1;
8187   int j;
8188   f64 before = 0;
8189   u32 random_add_del = 0;
8190   u32 *random_vector = 0;
8191   u32 random_seed = 0xdeaddabe;
8192
8193   /* Parse args required to build the message */
8194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8195     {
8196       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8197         prefix_set = 1;
8198       else if (unformat (i, "del"))
8199         is_add = 0;
8200       else if (unformat (i, "add"))
8201         is_add = 1;
8202       else if (unformat (i, "vrf %d", &vrf_id))
8203         ;
8204       else if (unformat (i, "count %d", &count))
8205         ;
8206       else if (unformat (i, "random"))
8207         random_add_del = 1;
8208       else if (unformat (i, "multipath"))
8209         is_multipath = 1;
8210       else if (unformat (i, "seed %d", &random_seed))
8211         ;
8212       else
8213         if (unformat
8214             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8215         {
8216           path_count++;
8217           if (8 == path_count)
8218             {
8219               errmsg ("max 8 paths");
8220               return -99;
8221             }
8222         }
8223       else
8224         {
8225           clib_warning ("parse error '%U'", format_unformat_error, i);
8226           return -99;
8227         }
8228     }
8229
8230   if (!path_count)
8231     {
8232       errmsg ("specify a path; via ...");
8233       return -99;
8234     }
8235   if (prefix_set == 0)
8236     {
8237       errmsg ("missing prefix");
8238       return -99;
8239     }
8240
8241   /* Generate a pile of unique, random routes */
8242   if (random_add_del)
8243     {
8244       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8245       u32 this_random_address;
8246       uword *random_hash;
8247
8248       random_hash = hash_create (count, sizeof (uword));
8249
8250       hash_set (random_hash, i->as_u32, 1);
8251       for (j = 0; j <= count; j++)
8252         {
8253           do
8254             {
8255               this_random_address = random_u32 (&random_seed);
8256               this_random_address =
8257                 clib_host_to_net_u32 (this_random_address);
8258             }
8259           while (hash_get (random_hash, this_random_address));
8260           vec_add1 (random_vector, this_random_address);
8261           hash_set (random_hash, this_random_address, 1);
8262         }
8263       hash_free (random_hash);
8264       set_ip4_address (&pfx.address, random_vector[0]);
8265     }
8266
8267   if (count > 1)
8268     {
8269       /* Turn on async mode */
8270       vam->async_mode = 1;
8271       vam->async_errors = 0;
8272       before = vat_time_now (vam);
8273     }
8274
8275   for (j = 0; j < count; j++)
8276     {
8277       /* Construct the API message */
8278       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8279
8280       mp->is_add = is_add;
8281       mp->is_multipath = is_multipath;
8282
8283       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8284       mp->route.table_id = ntohl (vrf_id);
8285       mp->route.n_paths = path_count;
8286
8287       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8288
8289       if (random_add_del)
8290         set_ip4_address (&pfx.address, random_vector[j + 1]);
8291       else
8292         increment_address (&pfx.address);
8293       /* send it... */
8294       S (mp);
8295       /* If we receive SIGTERM, stop now... */
8296       if (vam->do_exit)
8297         break;
8298     }
8299
8300   /* When testing multiple add/del ops, use a control-ping to sync */
8301   if (count > 1)
8302     {
8303       vl_api_control_ping_t *mp_ping;
8304       f64 after;
8305       f64 timeout;
8306
8307       /* Shut off async mode */
8308       vam->async_mode = 0;
8309
8310       MPING (CONTROL_PING, mp_ping);
8311       S (mp_ping);
8312
8313       timeout = vat_time_now (vam) + 1.0;
8314       while (vat_time_now (vam) < timeout)
8315         if (vam->result_ready == 1)
8316           goto out;
8317       vam->retval = -99;
8318
8319     out:
8320       if (vam->retval == -99)
8321         errmsg ("timeout");
8322
8323       if (vam->async_errors > 0)
8324         {
8325           errmsg ("%d asynchronous errors", vam->async_errors);
8326           vam->retval = -98;
8327         }
8328       vam->async_errors = 0;
8329       after = vat_time_now (vam);
8330
8331       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8332       if (j > 0)
8333         count = j;
8334
8335       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8336              count, after - before, count / (after - before));
8337     }
8338   else
8339     {
8340       int ret;
8341
8342       /* Wait for a reply... */
8343       W (ret);
8344       return ret;
8345     }
8346
8347   /* Return the good/bad news */
8348   return (vam->retval);
8349 }
8350
8351 static int
8352 api_ip_mroute_add_del (vat_main_t * vam)
8353 {
8354   unformat_input_t *i = vam->input;
8355   u8 path_set = 0, prefix_set = 0, is_add = 1;
8356   vl_api_ip_mroute_add_del_t *mp;
8357   mfib_entry_flags_t eflags = 0;
8358   vl_api_mfib_path_t path;
8359   vl_api_mprefix_t pfx = { };
8360   u32 vrf_id = 0;
8361   int ret;
8362
8363   /* Parse args required to build the message */
8364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8367         {
8368           prefix_set = 1;
8369           pfx.grp_address_length = htons (pfx.grp_address_length);
8370         }
8371       else if (unformat (i, "del"))
8372         is_add = 0;
8373       else if (unformat (i, "add"))
8374         is_add = 1;
8375       else if (unformat (i, "vrf %d", &vrf_id))
8376         ;
8377       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8378         path.itf_flags = htonl (path.itf_flags);
8379       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8380         ;
8381       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8382         path_set = 1;
8383       else
8384         {
8385           clib_warning ("parse error '%U'", format_unformat_error, i);
8386           return -99;
8387         }
8388     }
8389
8390   if (prefix_set == 0)
8391     {
8392       errmsg ("missing addresses\n");
8393       return -99;
8394     }
8395   if (path_set == 0)
8396     {
8397       errmsg ("missing path\n");
8398       return -99;
8399     }
8400
8401   /* Construct the API message */
8402   M (IP_MROUTE_ADD_DEL, mp);
8403
8404   mp->is_add = is_add;
8405   mp->is_multipath = 1;
8406
8407   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8408   mp->route.table_id = htonl (vrf_id);
8409   mp->route.n_paths = 1;
8410   mp->route.entry_flags = htonl (eflags);
8411
8412   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8413
8414   /* send it... */
8415   S (mp);
8416   /* Wait for a reply... */
8417   W (ret);
8418   return ret;
8419 }
8420
8421 static int
8422 api_mpls_table_add_del (vat_main_t * vam)
8423 {
8424   unformat_input_t *i = vam->input;
8425   vl_api_mpls_table_add_del_t *mp;
8426   u32 table_id = ~0;
8427   u8 is_add = 1;
8428   int ret = 0;
8429
8430   /* Parse args required to build the message */
8431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8432     {
8433       if (unformat (i, "table %d", &table_id))
8434         ;
8435       else if (unformat (i, "del"))
8436         is_add = 0;
8437       else if (unformat (i, "add"))
8438         is_add = 1;
8439       else
8440         {
8441           clib_warning ("parse error '%U'", format_unformat_error, i);
8442           return -99;
8443         }
8444     }
8445
8446   if (~0 == table_id)
8447     {
8448       errmsg ("missing table-ID");
8449       return -99;
8450     }
8451
8452   /* Construct the API message */
8453   M (MPLS_TABLE_ADD_DEL, mp);
8454
8455   mp->mt_table.mt_table_id = ntohl (table_id);
8456   mp->mt_is_add = is_add;
8457
8458   /* send it... */
8459   S (mp);
8460
8461   /* Wait for a reply... */
8462   W (ret);
8463
8464   return ret;
8465 }
8466
8467 static int
8468 api_mpls_route_add_del (vat_main_t * vam)
8469 {
8470   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8471   mpls_label_t local_label = MPLS_LABEL_INVALID;
8472   unformat_input_t *i = vam->input;
8473   vl_api_mpls_route_add_del_t *mp;
8474   vl_api_fib_path_t paths[8];
8475   int count = 1, j;
8476   f64 before = 0;
8477
8478   /* Parse args required to build the message */
8479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8480     {
8481       if (unformat (i, "%d", &local_label))
8482         ;
8483       else if (unformat (i, "eos"))
8484         is_eos = 1;
8485       else if (unformat (i, "non-eos"))
8486         is_eos = 0;
8487       else if (unformat (i, "del"))
8488         is_add = 0;
8489       else if (unformat (i, "add"))
8490         is_add = 1;
8491       else if (unformat (i, "multipath"))
8492         is_multipath = 1;
8493       else if (unformat (i, "count %d", &count))
8494         ;
8495       else
8496         if (unformat
8497             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8498         {
8499           path_count++;
8500           if (8 == path_count)
8501             {
8502               errmsg ("max 8 paths");
8503               return -99;
8504             }
8505         }
8506       else
8507         {
8508           clib_warning ("parse error '%U'", format_unformat_error, i);
8509           return -99;
8510         }
8511     }
8512
8513   if (!path_count)
8514     {
8515       errmsg ("specify a path; via ...");
8516       return -99;
8517     }
8518
8519   if (MPLS_LABEL_INVALID == local_label)
8520     {
8521       errmsg ("missing label");
8522       return -99;
8523     }
8524
8525   if (count > 1)
8526     {
8527       /* Turn on async mode */
8528       vam->async_mode = 1;
8529       vam->async_errors = 0;
8530       before = vat_time_now (vam);
8531     }
8532
8533   for (j = 0; j < count; j++)
8534     {
8535       /* Construct the API message */
8536       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8537
8538       mp->mr_is_add = is_add;
8539       mp->mr_is_multipath = is_multipath;
8540
8541       mp->mr_route.mr_label = local_label;
8542       mp->mr_route.mr_eos = is_eos;
8543       mp->mr_route.mr_table_id = 0;
8544       mp->mr_route.mr_n_paths = path_count;
8545
8546       clib_memcpy (&mp->mr_route.mr_paths, paths,
8547                    sizeof (paths[0]) * path_count);
8548
8549       local_label++;
8550
8551       /* send it... */
8552       S (mp);
8553       /* If we receive SIGTERM, stop now... */
8554       if (vam->do_exit)
8555         break;
8556     }
8557
8558   /* When testing multiple add/del ops, use a control-ping to sync */
8559   if (count > 1)
8560     {
8561       vl_api_control_ping_t *mp_ping;
8562       f64 after;
8563       f64 timeout;
8564
8565       /* Shut off async mode */
8566       vam->async_mode = 0;
8567
8568       MPING (CONTROL_PING, mp_ping);
8569       S (mp_ping);
8570
8571       timeout = vat_time_now (vam) + 1.0;
8572       while (vat_time_now (vam) < timeout)
8573         if (vam->result_ready == 1)
8574           goto out;
8575       vam->retval = -99;
8576
8577     out:
8578       if (vam->retval == -99)
8579         errmsg ("timeout");
8580
8581       if (vam->async_errors > 0)
8582         {
8583           errmsg ("%d asynchronous errors", vam->async_errors);
8584           vam->retval = -98;
8585         }
8586       vam->async_errors = 0;
8587       after = vat_time_now (vam);
8588
8589       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8590       if (j > 0)
8591         count = j;
8592
8593       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8594              count, after - before, count / (after - before));
8595     }
8596   else
8597     {
8598       int ret;
8599
8600       /* Wait for a reply... */
8601       W (ret);
8602       return ret;
8603     }
8604
8605   /* Return the good/bad news */
8606   return (vam->retval);
8607   return (0);
8608 }
8609
8610 static int
8611 api_mpls_ip_bind_unbind (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_mpls_ip_bind_unbind_t *mp;
8615   u32 ip_table_id = 0;
8616   u8 is_bind = 1;
8617   vl_api_prefix_t pfx;
8618   u8 prefix_set = 0;
8619   mpls_label_t local_label = MPLS_LABEL_INVALID;
8620   int ret;
8621
8622   /* Parse args required to build the message */
8623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8624     {
8625       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8626         prefix_set = 1;
8627       else if (unformat (i, "%d", &local_label))
8628         ;
8629       else if (unformat (i, "table-id %d", &ip_table_id))
8630         ;
8631       else if (unformat (i, "unbind"))
8632         is_bind = 0;
8633       else if (unformat (i, "bind"))
8634         is_bind = 1;
8635       else
8636         {
8637           clib_warning ("parse error '%U'", format_unformat_error, i);
8638           return -99;
8639         }
8640     }
8641
8642   if (!prefix_set)
8643     {
8644       errmsg ("IP prefix not set");
8645       return -99;
8646     }
8647
8648   if (MPLS_LABEL_INVALID == local_label)
8649     {
8650       errmsg ("missing label");
8651       return -99;
8652     }
8653
8654   /* Construct the API message */
8655   M (MPLS_IP_BIND_UNBIND, mp);
8656
8657   mp->mb_is_bind = is_bind;
8658   mp->mb_ip_table_id = ntohl (ip_table_id);
8659   mp->mb_mpls_table_id = 0;
8660   mp->mb_label = ntohl (local_label);
8661   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8662
8663   /* send it... */
8664   S (mp);
8665
8666   /* Wait for a reply... */
8667   W (ret);
8668   return ret;
8669   return (0);
8670 }
8671
8672 static int
8673 api_sr_mpls_policy_add (vat_main_t * vam)
8674 {
8675   unformat_input_t *i = vam->input;
8676   vl_api_sr_mpls_policy_add_t *mp;
8677   u32 bsid = 0;
8678   u32 weight = 1;
8679   u8 type = 0;
8680   u8 n_segments = 0;
8681   u32 sid;
8682   u32 *segments = NULL;
8683   int ret;
8684
8685   /* Parse args required to build the message */
8686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8687     {
8688       if (unformat (i, "bsid %d", &bsid))
8689         ;
8690       else if (unformat (i, "weight %d", &weight))
8691         ;
8692       else if (unformat (i, "spray"))
8693         type = 1;
8694       else if (unformat (i, "next %d", &sid))
8695         {
8696           n_segments += 1;
8697           vec_add1 (segments, htonl (sid));
8698         }
8699       else
8700         {
8701           clib_warning ("parse error '%U'", format_unformat_error, i);
8702           return -99;
8703         }
8704     }
8705
8706   if (bsid == 0)
8707     {
8708       errmsg ("bsid not set");
8709       return -99;
8710     }
8711
8712   if (n_segments == 0)
8713     {
8714       errmsg ("no sid in segment stack");
8715       return -99;
8716     }
8717
8718   /* Construct the API message */
8719   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8720
8721   mp->bsid = htonl (bsid);
8722   mp->weight = htonl (weight);
8723   mp->type = type;
8724   mp->n_segments = n_segments;
8725   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8726   vec_free (segments);
8727
8728   /* send it... */
8729   S (mp);
8730
8731   /* Wait for a reply... */
8732   W (ret);
8733   return ret;
8734 }
8735
8736 static int
8737 api_sr_mpls_policy_del (vat_main_t * vam)
8738 {
8739   unformat_input_t *i = vam->input;
8740   vl_api_sr_mpls_policy_del_t *mp;
8741   u32 bsid = 0;
8742   int ret;
8743
8744   /* Parse args required to build the message */
8745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8746     {
8747       if (unformat (i, "bsid %d", &bsid))
8748         ;
8749       else
8750         {
8751           clib_warning ("parse error '%U'", format_unformat_error, i);
8752           return -99;
8753         }
8754     }
8755
8756   if (bsid == 0)
8757     {
8758       errmsg ("bsid not set");
8759       return -99;
8760     }
8761
8762   /* Construct the API message */
8763   M (SR_MPLS_POLICY_DEL, mp);
8764
8765   mp->bsid = htonl (bsid);
8766
8767   /* send it... */
8768   S (mp);
8769
8770   /* Wait for a reply... */
8771   W (ret);
8772   return ret;
8773 }
8774
8775 static int
8776 api_bier_table_add_del (vat_main_t * vam)
8777 {
8778   unformat_input_t *i = vam->input;
8779   vl_api_bier_table_add_del_t *mp;
8780   u8 is_add = 1;
8781   u32 set = 0, sub_domain = 0, hdr_len = 3;
8782   mpls_label_t local_label = MPLS_LABEL_INVALID;
8783   int ret;
8784
8785   /* Parse args required to build the message */
8786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8787     {
8788       if (unformat (i, "sub-domain %d", &sub_domain))
8789         ;
8790       else if (unformat (i, "set %d", &set))
8791         ;
8792       else if (unformat (i, "label %d", &local_label))
8793         ;
8794       else if (unformat (i, "hdr-len %d", &hdr_len))
8795         ;
8796       else if (unformat (i, "add"))
8797         is_add = 1;
8798       else if (unformat (i, "del"))
8799         is_add = 0;
8800       else
8801         {
8802           clib_warning ("parse error '%U'", format_unformat_error, i);
8803           return -99;
8804         }
8805     }
8806
8807   if (MPLS_LABEL_INVALID == local_label)
8808     {
8809       errmsg ("missing label\n");
8810       return -99;
8811     }
8812
8813   /* Construct the API message */
8814   M (BIER_TABLE_ADD_DEL, mp);
8815
8816   mp->bt_is_add = is_add;
8817   mp->bt_label = ntohl (local_label);
8818   mp->bt_tbl_id.bt_set = set;
8819   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8820   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8821
8822   /* send it... */
8823   S (mp);
8824
8825   /* Wait for a reply... */
8826   W (ret);
8827
8828   return (ret);
8829 }
8830
8831 static int
8832 api_bier_route_add_del (vat_main_t * vam)
8833 {
8834   unformat_input_t *i = vam->input;
8835   vl_api_bier_route_add_del_t *mp;
8836   u8 is_add = 1;
8837   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8838   ip4_address_t v4_next_hop_address;
8839   ip6_address_t v6_next_hop_address;
8840   u8 next_hop_set = 0;
8841   u8 next_hop_proto_is_ip4 = 1;
8842   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8843   int ret;
8844
8845   /* Parse args required to build the message */
8846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8847     {
8848       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8849         {
8850           next_hop_proto_is_ip4 = 1;
8851           next_hop_set = 1;
8852         }
8853       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8854         {
8855           next_hop_proto_is_ip4 = 0;
8856           next_hop_set = 1;
8857         }
8858       if (unformat (i, "sub-domain %d", &sub_domain))
8859         ;
8860       else if (unformat (i, "set %d", &set))
8861         ;
8862       else if (unformat (i, "hdr-len %d", &hdr_len))
8863         ;
8864       else if (unformat (i, "bp %d", &bp))
8865         ;
8866       else if (unformat (i, "add"))
8867         is_add = 1;
8868       else if (unformat (i, "del"))
8869         is_add = 0;
8870       else if (unformat (i, "out-label %d", &next_hop_out_label))
8871         ;
8872       else
8873         {
8874           clib_warning ("parse error '%U'", format_unformat_error, i);
8875           return -99;
8876         }
8877     }
8878
8879   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8880     {
8881       errmsg ("next hop / label set\n");
8882       return -99;
8883     }
8884   if (0 == bp)
8885     {
8886       errmsg ("bit=position not set\n");
8887       return -99;
8888     }
8889
8890   /* Construct the API message */
8891   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8892
8893   mp->br_is_add = is_add;
8894   mp->br_route.br_tbl_id.bt_set = set;
8895   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8896   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8897   mp->br_route.br_bp = ntohs (bp);
8898   mp->br_route.br_n_paths = 1;
8899   mp->br_route.br_paths[0].n_labels = 1;
8900   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8901   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8902                                     FIB_API_PATH_NH_PROTO_IP4 :
8903                                     FIB_API_PATH_NH_PROTO_IP6);
8904
8905   if (next_hop_proto_is_ip4)
8906     {
8907       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8908                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8909     }
8910   else
8911     {
8912       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8913                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8914     }
8915
8916   /* send it... */
8917   S (mp);
8918
8919   /* Wait for a reply... */
8920   W (ret);
8921
8922   return (ret);
8923 }
8924
8925 static int
8926 api_proxy_arp_add_del (vat_main_t * vam)
8927 {
8928   unformat_input_t *i = vam->input;
8929   vl_api_proxy_arp_add_del_t *mp;
8930   u32 vrf_id = 0;
8931   u8 is_add = 1;
8932   vl_api_ip4_address_t lo, hi;
8933   u8 range_set = 0;
8934   int ret;
8935
8936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8937     {
8938       if (unformat (i, "vrf %d", &vrf_id))
8939         ;
8940       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8941                          unformat_vl_api_ip4_address, &hi))
8942         range_set = 1;
8943       else if (unformat (i, "del"))
8944         is_add = 0;
8945       else
8946         {
8947           clib_warning ("parse error '%U'", format_unformat_error, i);
8948           return -99;
8949         }
8950     }
8951
8952   if (range_set == 0)
8953     {
8954       errmsg ("address range not set");
8955       return -99;
8956     }
8957
8958   M (PROXY_ARP_ADD_DEL, mp);
8959
8960   mp->proxy.table_id = ntohl (vrf_id);
8961   mp->is_add = is_add;
8962   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8963   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8964
8965   S (mp);
8966   W (ret);
8967   return ret;
8968 }
8969
8970 static int
8971 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8972 {
8973   unformat_input_t *i = vam->input;
8974   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8975   u32 sw_if_index;
8976   u8 enable = 1;
8977   u8 sw_if_index_set = 0;
8978   int ret;
8979
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8983         sw_if_index_set = 1;
8984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8985         sw_if_index_set = 1;
8986       else if (unformat (i, "enable"))
8987         enable = 1;
8988       else if (unformat (i, "disable"))
8989         enable = 0;
8990       else
8991         {
8992           clib_warning ("parse error '%U'", format_unformat_error, i);
8993           return -99;
8994         }
8995     }
8996
8997   if (sw_if_index_set == 0)
8998     {
8999       errmsg ("missing interface name or sw_if_index");
9000       return -99;
9001     }
9002
9003   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9004
9005   mp->sw_if_index = ntohl (sw_if_index);
9006   mp->enable_disable = enable;
9007
9008   S (mp);
9009   W (ret);
9010   return ret;
9011 }
9012
9013 static int
9014 api_mpls_tunnel_add_del (vat_main_t * vam)
9015 {
9016   unformat_input_t *i = vam->input;
9017   vl_api_mpls_tunnel_add_del_t *mp;
9018
9019   vl_api_fib_path_t paths[8];
9020   u32 sw_if_index = ~0;
9021   u8 path_count = 0;
9022   u8 l2_only = 0;
9023   u8 is_add = 1;
9024   int ret;
9025
9026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9027     {
9028       if (unformat (i, "add"))
9029         is_add = 1;
9030       else
9031         if (unformat
9032             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9033         is_add = 0;
9034       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9035         is_add = 0;
9036       else if (unformat (i, "l2-only"))
9037         l2_only = 1;
9038       else
9039         if (unformat
9040             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9041         {
9042           path_count++;
9043           if (8 == path_count)
9044             {
9045               errmsg ("max 8 paths");
9046               return -99;
9047             }
9048         }
9049       else
9050         {
9051           clib_warning ("parse error '%U'", format_unformat_error, i);
9052           return -99;
9053         }
9054     }
9055
9056   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9057
9058   mp->mt_is_add = is_add;
9059   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9060   mp->mt_tunnel.mt_l2_only = l2_only;
9061   mp->mt_tunnel.mt_is_multicast = 0;
9062   mp->mt_tunnel.mt_n_paths = path_count;
9063
9064   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9065                sizeof (paths[0]) * path_count);
9066
9067   S (mp);
9068   W (ret);
9069   return ret;
9070 }
9071
9072 static int
9073 api_sw_interface_set_unnumbered (vat_main_t * vam)
9074 {
9075   unformat_input_t *i = vam->input;
9076   vl_api_sw_interface_set_unnumbered_t *mp;
9077   u32 sw_if_index;
9078   u32 unnum_sw_index = ~0;
9079   u8 is_add = 1;
9080   u8 sw_if_index_set = 0;
9081   int ret;
9082
9083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9084     {
9085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9086         sw_if_index_set = 1;
9087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9088         sw_if_index_set = 1;
9089       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9090         ;
9091       else if (unformat (i, "del"))
9092         is_add = 0;
9093       else
9094         {
9095           clib_warning ("parse error '%U'", format_unformat_error, i);
9096           return -99;
9097         }
9098     }
9099
9100   if (sw_if_index_set == 0)
9101     {
9102       errmsg ("missing interface name or sw_if_index");
9103       return -99;
9104     }
9105
9106   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9107
9108   mp->sw_if_index = ntohl (sw_if_index);
9109   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9110   mp->is_add = is_add;
9111
9112   S (mp);
9113   W (ret);
9114   return ret;
9115 }
9116
9117 static int
9118 api_ip_neighbor_add_del (vat_main_t * vam)
9119 {
9120   vl_api_mac_address_t mac_address;
9121   unformat_input_t *i = vam->input;
9122   vl_api_ip_neighbor_add_del_t *mp;
9123   vl_api_address_t ip_address;
9124   u32 sw_if_index;
9125   u8 sw_if_index_set = 0;
9126   u8 is_add = 1;
9127   u8 mac_set = 0;
9128   u8 address_set = 0;
9129   int ret;
9130   ip_neighbor_flags_t flags;
9131
9132   flags = IP_NEIGHBOR_FLAG_NONE;
9133   clib_memset (&ip_address, 0, sizeof (ip_address));
9134   clib_memset (&mac_address, 0, sizeof (mac_address));
9135
9136   /* Parse args required to build the message */
9137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9138     {
9139       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9140         {
9141           mac_set = 1;
9142         }
9143       else if (unformat (i, "del"))
9144         is_add = 0;
9145       else
9146         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9147         sw_if_index_set = 1;
9148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9149         sw_if_index_set = 1;
9150       else if (unformat (i, "static"))
9151         flags |= IP_NEIGHBOR_FLAG_STATIC;
9152       else if (unformat (i, "no-fib-entry"))
9153         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9154       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9155         address_set = 1;
9156       else
9157         {
9158           clib_warning ("parse error '%U'", format_unformat_error, i);
9159           return -99;
9160         }
9161     }
9162
9163   if (sw_if_index_set == 0)
9164     {
9165       errmsg ("missing interface name or sw_if_index");
9166       return -99;
9167     }
9168   if (!address_set)
9169     {
9170       errmsg ("no address set");
9171       return -99;
9172     }
9173
9174   /* Construct the API message */
9175   M (IP_NEIGHBOR_ADD_DEL, mp);
9176
9177   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9178   mp->is_add = is_add;
9179   mp->neighbor.flags = htonl (flags);
9180   if (mac_set)
9181     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9182                  sizeof (mac_address));
9183   if (address_set)
9184     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9185
9186   /* send it... */
9187   S (mp);
9188
9189   /* Wait for a reply, return good/bad news  */
9190   W (ret);
9191   return ret;
9192 }
9193
9194 static int
9195 api_create_vlan_subif (vat_main_t * vam)
9196 {
9197   unformat_input_t *i = vam->input;
9198   vl_api_create_vlan_subif_t *mp;
9199   u32 sw_if_index;
9200   u8 sw_if_index_set = 0;
9201   u32 vlan_id;
9202   u8 vlan_id_set = 0;
9203   int ret;
9204
9205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (i, "sw_if_index %d", &sw_if_index))
9208         sw_if_index_set = 1;
9209       else
9210         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9211         sw_if_index_set = 1;
9212       else if (unformat (i, "vlan %d", &vlan_id))
9213         vlan_id_set = 1;
9214       else
9215         {
9216           clib_warning ("parse error '%U'", format_unformat_error, i);
9217           return -99;
9218         }
9219     }
9220
9221   if (sw_if_index_set == 0)
9222     {
9223       errmsg ("missing interface name or sw_if_index");
9224       return -99;
9225     }
9226
9227   if (vlan_id_set == 0)
9228     {
9229       errmsg ("missing vlan_id");
9230       return -99;
9231     }
9232   M (CREATE_VLAN_SUBIF, mp);
9233
9234   mp->sw_if_index = ntohl (sw_if_index);
9235   mp->vlan_id = ntohl (vlan_id);
9236
9237   S (mp);
9238   W (ret);
9239   return ret;
9240 }
9241
9242 #define foreach_create_subif_bit                \
9243 _(no_tags)                                      \
9244 _(one_tag)                                      \
9245 _(two_tags)                                     \
9246 _(dot1ad)                                       \
9247 _(exact_match)                                  \
9248 _(default_sub)                                  \
9249 _(outer_vlan_id_any)                            \
9250 _(inner_vlan_id_any)
9251
9252 static int
9253 api_create_subif (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_create_subif_t *mp;
9257   u32 sw_if_index;
9258   u8 sw_if_index_set = 0;
9259   u32 sub_id;
9260   u8 sub_id_set = 0;
9261   u32 no_tags = 0;
9262   u32 one_tag = 0;
9263   u32 two_tags = 0;
9264   u32 dot1ad = 0;
9265   u32 exact_match = 0;
9266   u32 default_sub = 0;
9267   u32 outer_vlan_id_any = 0;
9268   u32 inner_vlan_id_any = 0;
9269   u32 tmp;
9270   u16 outer_vlan_id = 0;
9271   u16 inner_vlan_id = 0;
9272   int ret;
9273
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "sw_if_index %d", &sw_if_index))
9277         sw_if_index_set = 1;
9278       else
9279         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "sub_id %d", &sub_id))
9282         sub_id_set = 1;
9283       else if (unformat (i, "outer_vlan_id %d", &tmp))
9284         outer_vlan_id = tmp;
9285       else if (unformat (i, "inner_vlan_id %d", &tmp))
9286         inner_vlan_id = tmp;
9287
9288 #define _(a) else if (unformat (i, #a)) a = 1 ;
9289       foreach_create_subif_bit
9290 #undef _
9291         else
9292         {
9293           clib_warning ("parse error '%U'", format_unformat_error, i);
9294           return -99;
9295         }
9296     }
9297
9298   if (sw_if_index_set == 0)
9299     {
9300       errmsg ("missing interface name or sw_if_index");
9301       return -99;
9302     }
9303
9304   if (sub_id_set == 0)
9305     {
9306       errmsg ("missing sub_id");
9307       return -99;
9308     }
9309   M (CREATE_SUBIF, mp);
9310
9311   mp->sw_if_index = ntohl (sw_if_index);
9312   mp->sub_id = ntohl (sub_id);
9313
9314 #define _(a) mp->a = a;
9315   foreach_create_subif_bit;
9316 #undef _
9317
9318   mp->outer_vlan_id = ntohs (outer_vlan_id);
9319   mp->inner_vlan_id = ntohs (inner_vlan_id);
9320
9321   S (mp);
9322   W (ret);
9323   return ret;
9324 }
9325
9326 static int
9327 api_reset_fib (vat_main_t * vam)
9328 {
9329   unformat_input_t *i = vam->input;
9330   vl_api_reset_fib_t *mp;
9331   u32 vrf_id = 0;
9332   u8 is_ipv6 = 0;
9333   u8 vrf_id_set = 0;
9334
9335   int ret;
9336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9337     {
9338       if (unformat (i, "vrf %d", &vrf_id))
9339         vrf_id_set = 1;
9340       else if (unformat (i, "ipv6"))
9341         is_ipv6 = 1;
9342       else
9343         {
9344           clib_warning ("parse error '%U'", format_unformat_error, i);
9345           return -99;
9346         }
9347     }
9348
9349   if (vrf_id_set == 0)
9350     {
9351       errmsg ("missing vrf id");
9352       return -99;
9353     }
9354
9355   M (RESET_FIB, mp);
9356
9357   mp->vrf_id = ntohl (vrf_id);
9358   mp->is_ipv6 = is_ipv6;
9359
9360   S (mp);
9361   W (ret);
9362   return ret;
9363 }
9364
9365 static int
9366 api_dhcp_proxy_config (vat_main_t * vam)
9367 {
9368   unformat_input_t *i = vam->input;
9369   vl_api_dhcp_proxy_config_t *mp;
9370   u32 rx_vrf_id = 0;
9371   u32 server_vrf_id = 0;
9372   u8 is_add = 1;
9373   u8 v4_address_set = 0;
9374   u8 v6_address_set = 0;
9375   ip4_address_t v4address;
9376   ip6_address_t v6address;
9377   u8 v4_src_address_set = 0;
9378   u8 v6_src_address_set = 0;
9379   ip4_address_t v4srcaddress;
9380   ip6_address_t v6srcaddress;
9381   int ret;
9382
9383   /* Parse args required to build the message */
9384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9385     {
9386       if (unformat (i, "del"))
9387         is_add = 0;
9388       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9389         ;
9390       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9391         ;
9392       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9393         v4_address_set = 1;
9394       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9395         v6_address_set = 1;
9396       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9397         v4_src_address_set = 1;
9398       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9399         v6_src_address_set = 1;
9400       else
9401         break;
9402     }
9403
9404   if (v4_address_set && v6_address_set)
9405     {
9406       errmsg ("both v4 and v6 server addresses set");
9407       return -99;
9408     }
9409   if (!v4_address_set && !v6_address_set)
9410     {
9411       errmsg ("no server addresses set");
9412       return -99;
9413     }
9414
9415   if (v4_src_address_set && v6_src_address_set)
9416     {
9417       errmsg ("both v4 and v6  src addresses set");
9418       return -99;
9419     }
9420   if (!v4_src_address_set && !v6_src_address_set)
9421     {
9422       errmsg ("no src addresses set");
9423       return -99;
9424     }
9425
9426   if (!(v4_src_address_set && v4_address_set) &&
9427       !(v6_src_address_set && v6_address_set))
9428     {
9429       errmsg ("no matching server and src addresses set");
9430       return -99;
9431     }
9432
9433   /* Construct the API message */
9434   M (DHCP_PROXY_CONFIG, mp);
9435
9436   mp->is_add = is_add;
9437   mp->rx_vrf_id = ntohl (rx_vrf_id);
9438   mp->server_vrf_id = ntohl (server_vrf_id);
9439   if (v6_address_set)
9440     {
9441       mp->is_ipv6 = 1;
9442       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9443       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9444     }
9445   else
9446     {
9447       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9448       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9449     }
9450
9451   /* send it... */
9452   S (mp);
9453
9454   /* Wait for a reply, return good/bad news  */
9455   W (ret);
9456   return ret;
9457 }
9458
9459 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9460 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9461
9462 static void
9463 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9464 {
9465   vat_main_t *vam = &vat_main;
9466   u32 i, count = mp->count;
9467   vl_api_dhcp_server_t *s;
9468
9469   if (mp->is_ipv6)
9470     print (vam->ofp,
9471            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9472            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9473            ntohl (mp->rx_vrf_id),
9474            format_ip6_address, mp->dhcp_src_address,
9475            mp->vss_type, mp->vss_vpn_ascii_id,
9476            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9477   else
9478     print (vam->ofp,
9479            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9480            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9481            ntohl (mp->rx_vrf_id),
9482            format_ip4_address, mp->dhcp_src_address,
9483            mp->vss_type, mp->vss_vpn_ascii_id,
9484            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9485
9486   for (i = 0; i < count; i++)
9487     {
9488       s = &mp->servers[i];
9489
9490       if (mp->is_ipv6)
9491         print (vam->ofp,
9492                " Server Table-ID %d, Server Address %U",
9493                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9494       else
9495         print (vam->ofp,
9496                " Server Table-ID %d, Server Address %U",
9497                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9498     }
9499 }
9500
9501 static void vl_api_dhcp_proxy_details_t_handler_json
9502   (vl_api_dhcp_proxy_details_t * mp)
9503 {
9504   vat_main_t *vam = &vat_main;
9505   vat_json_node_t *node = NULL;
9506   u32 i, count = mp->count;
9507   struct in_addr ip4;
9508   struct in6_addr ip6;
9509   vl_api_dhcp_server_t *s;
9510
9511   if (VAT_JSON_ARRAY != vam->json_tree.type)
9512     {
9513       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9514       vat_json_init_array (&vam->json_tree);
9515     }
9516   node = vat_json_array_add (&vam->json_tree);
9517
9518   vat_json_init_object (node);
9519   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9520   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9521                              sizeof (mp->vss_type));
9522   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9523                                    mp->vss_vpn_ascii_id);
9524   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9525   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9526
9527   if (mp->is_ipv6)
9528     {
9529       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9530       vat_json_object_add_ip6 (node, "src_address", ip6);
9531     }
9532   else
9533     {
9534       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9535       vat_json_object_add_ip4 (node, "src_address", ip4);
9536     }
9537
9538   for (i = 0; i < count; i++)
9539     {
9540       s = &mp->servers[i];
9541
9542       vat_json_object_add_uint (node, "server-table-id",
9543                                 ntohl (s->server_vrf_id));
9544
9545       if (mp->is_ipv6)
9546         {
9547           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9548           vat_json_object_add_ip4 (node, "src_address", ip4);
9549         }
9550       else
9551         {
9552           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9553           vat_json_object_add_ip6 (node, "server_address", ip6);
9554         }
9555     }
9556 }
9557
9558 static int
9559 api_dhcp_proxy_dump (vat_main_t * vam)
9560 {
9561   unformat_input_t *i = vam->input;
9562   vl_api_control_ping_t *mp_ping;
9563   vl_api_dhcp_proxy_dump_t *mp;
9564   u8 is_ipv6 = 0;
9565   int ret;
9566
9567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9568     {
9569       if (unformat (i, "ipv6"))
9570         is_ipv6 = 1;
9571       else
9572         {
9573           clib_warning ("parse error '%U'", format_unformat_error, i);
9574           return -99;
9575         }
9576     }
9577
9578   M (DHCP_PROXY_DUMP, mp);
9579
9580   mp->is_ip6 = is_ipv6;
9581   S (mp);
9582
9583   /* Use a control ping for synchronization */
9584   MPING (CONTROL_PING, mp_ping);
9585   S (mp_ping);
9586
9587   W (ret);
9588   return ret;
9589 }
9590
9591 static int
9592 api_dhcp_proxy_set_vss (vat_main_t * vam)
9593 {
9594   unformat_input_t *i = vam->input;
9595   vl_api_dhcp_proxy_set_vss_t *mp;
9596   u8 is_ipv6 = 0;
9597   u8 is_add = 1;
9598   u32 tbl_id = ~0;
9599   u8 vss_type = VSS_TYPE_DEFAULT;
9600   u8 *vpn_ascii_id = 0;
9601   u32 oui = 0;
9602   u32 fib_id = 0;
9603   int ret;
9604
9605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9606     {
9607       if (unformat (i, "tbl_id %d", &tbl_id))
9608         ;
9609       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9610         vss_type = VSS_TYPE_ASCII;
9611       else if (unformat (i, "fib_id %d", &fib_id))
9612         vss_type = VSS_TYPE_VPN_ID;
9613       else if (unformat (i, "oui %d", &oui))
9614         vss_type = VSS_TYPE_VPN_ID;
9615       else if (unformat (i, "ipv6"))
9616         is_ipv6 = 1;
9617       else if (unformat (i, "del"))
9618         is_add = 0;
9619       else
9620         break;
9621     }
9622
9623   if (tbl_id == ~0)
9624     {
9625       errmsg ("missing tbl_id ");
9626       vec_free (vpn_ascii_id);
9627       return -99;
9628     }
9629
9630   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9631     {
9632       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9633       vec_free (vpn_ascii_id);
9634       return -99;
9635     }
9636
9637   M (DHCP_PROXY_SET_VSS, mp);
9638   mp->tbl_id = ntohl (tbl_id);
9639   mp->vss_type = vss_type;
9640   if (vpn_ascii_id)
9641     {
9642       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9643       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9644     }
9645   mp->vpn_index = ntohl (fib_id);
9646   mp->oui = ntohl (oui);
9647   mp->is_ipv6 = is_ipv6;
9648   mp->is_add = is_add;
9649
9650   S (mp);
9651   W (ret);
9652
9653   vec_free (vpn_ascii_id);
9654   return ret;
9655 }
9656
9657 static int
9658 api_dhcp_client_config (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_dhcp_client_config_t *mp;
9662   u32 sw_if_index;
9663   u8 sw_if_index_set = 0;
9664   u8 is_add = 1;
9665   u8 *hostname = 0;
9666   u8 disable_event = 0;
9667   int ret;
9668
9669   /* Parse args required to build the message */
9670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9671     {
9672       if (unformat (i, "del"))
9673         is_add = 0;
9674       else
9675         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9676         sw_if_index_set = 1;
9677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9678         sw_if_index_set = 1;
9679       else if (unformat (i, "hostname %s", &hostname))
9680         ;
9681       else if (unformat (i, "disable_event"))
9682         disable_event = 1;
9683       else
9684         break;
9685     }
9686
9687   if (sw_if_index_set == 0)
9688     {
9689       errmsg ("missing interface name or sw_if_index");
9690       return -99;
9691     }
9692
9693   if (vec_len (hostname) > 63)
9694     {
9695       errmsg ("hostname too long");
9696     }
9697   vec_add1 (hostname, 0);
9698
9699   /* Construct the API message */
9700   M (DHCP_CLIENT_CONFIG, mp);
9701
9702   mp->is_add = is_add;
9703   mp->client.sw_if_index = htonl (sw_if_index);
9704   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9705   vec_free (hostname);
9706   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9707   mp->client.pid = htonl (getpid ());
9708
9709   /* send it... */
9710   S (mp);
9711
9712   /* Wait for a reply, return good/bad news  */
9713   W (ret);
9714   return ret;
9715 }
9716
9717 static int
9718 api_set_ip_flow_hash (vat_main_t * vam)
9719 {
9720   unformat_input_t *i = vam->input;
9721   vl_api_set_ip_flow_hash_t *mp;
9722   u32 vrf_id = 0;
9723   u8 is_ipv6 = 0;
9724   u8 vrf_id_set = 0;
9725   u8 src = 0;
9726   u8 dst = 0;
9727   u8 sport = 0;
9728   u8 dport = 0;
9729   u8 proto = 0;
9730   u8 reverse = 0;
9731   int ret;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "vrf %d", &vrf_id))
9736         vrf_id_set = 1;
9737       else if (unformat (i, "ipv6"))
9738         is_ipv6 = 1;
9739       else if (unformat (i, "src"))
9740         src = 1;
9741       else if (unformat (i, "dst"))
9742         dst = 1;
9743       else if (unformat (i, "sport"))
9744         sport = 1;
9745       else if (unformat (i, "dport"))
9746         dport = 1;
9747       else if (unformat (i, "proto"))
9748         proto = 1;
9749       else if (unformat (i, "reverse"))
9750         reverse = 1;
9751
9752       else
9753         {
9754           clib_warning ("parse error '%U'", format_unformat_error, i);
9755           return -99;
9756         }
9757     }
9758
9759   if (vrf_id_set == 0)
9760     {
9761       errmsg ("missing vrf id");
9762       return -99;
9763     }
9764
9765   M (SET_IP_FLOW_HASH, mp);
9766   mp->src = src;
9767   mp->dst = dst;
9768   mp->sport = sport;
9769   mp->dport = dport;
9770   mp->proto = proto;
9771   mp->reverse = reverse;
9772   mp->vrf_id = ntohl (vrf_id);
9773   mp->is_ipv6 = is_ipv6;
9774
9775   S (mp);
9776   W (ret);
9777   return ret;
9778 }
9779
9780 static int
9781 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9782 {
9783   unformat_input_t *i = vam->input;
9784   vl_api_sw_interface_ip6_enable_disable_t *mp;
9785   u32 sw_if_index;
9786   u8 sw_if_index_set = 0;
9787   u8 enable = 0;
9788   int ret;
9789
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9793         sw_if_index_set = 1;
9794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9795         sw_if_index_set = 1;
9796       else if (unformat (i, "enable"))
9797         enable = 1;
9798       else if (unformat (i, "disable"))
9799         enable = 0;
9800       else
9801         {
9802           clib_warning ("parse error '%U'", format_unformat_error, i);
9803           return -99;
9804         }
9805     }
9806
9807   if (sw_if_index_set == 0)
9808     {
9809       errmsg ("missing interface name or sw_if_index");
9810       return -99;
9811     }
9812
9813   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9814
9815   mp->sw_if_index = ntohl (sw_if_index);
9816   mp->enable = enable;
9817
9818   S (mp);
9819   W (ret);
9820   return ret;
9821 }
9822
9823 static int
9824 api_ip6nd_proxy_add_del (vat_main_t * vam)
9825 {
9826   unformat_input_t *i = vam->input;
9827   vl_api_ip6nd_proxy_add_del_t *mp;
9828   u32 sw_if_index = ~0;
9829   u8 v6_address_set = 0;
9830   vl_api_ip6_address_t v6address;
9831   u8 is_del = 0;
9832   int ret;
9833
9834   /* Parse args required to build the message */
9835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9838         ;
9839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9840         ;
9841       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9842         v6_address_set = 1;
9843       if (unformat (i, "del"))
9844         is_del = 1;
9845       else
9846         {
9847           clib_warning ("parse error '%U'", format_unformat_error, i);
9848           return -99;
9849         }
9850     }
9851
9852   if (sw_if_index == ~0)
9853     {
9854       errmsg ("missing interface name or sw_if_index");
9855       return -99;
9856     }
9857   if (!v6_address_set)
9858     {
9859       errmsg ("no address set");
9860       return -99;
9861     }
9862
9863   /* Construct the API message */
9864   M (IP6ND_PROXY_ADD_DEL, mp);
9865
9866   mp->is_del = is_del;
9867   mp->sw_if_index = ntohl (sw_if_index);
9868   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9869
9870   /* send it... */
9871   S (mp);
9872
9873   /* Wait for a reply, return good/bad news  */
9874   W (ret);
9875   return ret;
9876 }
9877
9878 static int
9879 api_ip6nd_proxy_dump (vat_main_t * vam)
9880 {
9881   vl_api_ip6nd_proxy_dump_t *mp;
9882   vl_api_control_ping_t *mp_ping;
9883   int ret;
9884
9885   M (IP6ND_PROXY_DUMP, mp);
9886
9887   S (mp);
9888
9889   /* Use a control ping for synchronization */
9890   MPING (CONTROL_PING, mp_ping);
9891   S (mp_ping);
9892
9893   W (ret);
9894   return ret;
9895 }
9896
9897 static void vl_api_ip6nd_proxy_details_t_handler
9898   (vl_api_ip6nd_proxy_details_t * mp)
9899 {
9900   vat_main_t *vam = &vat_main;
9901
9902   print (vam->ofp, "host %U sw_if_index %d",
9903          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9904 }
9905
9906 static void vl_api_ip6nd_proxy_details_t_handler_json
9907   (vl_api_ip6nd_proxy_details_t * mp)
9908 {
9909   vat_main_t *vam = &vat_main;
9910   struct in6_addr ip6;
9911   vat_json_node_t *node = NULL;
9912
9913   if (VAT_JSON_ARRAY != vam->json_tree.type)
9914     {
9915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9916       vat_json_init_array (&vam->json_tree);
9917     }
9918   node = vat_json_array_add (&vam->json_tree);
9919
9920   vat_json_init_object (node);
9921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9922
9923   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9924   vat_json_object_add_ip6 (node, "host", ip6);
9925 }
9926
9927 static int
9928 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9929 {
9930   unformat_input_t *i = vam->input;
9931   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9932   u32 sw_if_index;
9933   u8 sw_if_index_set = 0;
9934   u8 v6_address_set = 0;
9935   vl_api_prefix_t pfx;
9936   u8 use_default = 0;
9937   u8 no_advertise = 0;
9938   u8 off_link = 0;
9939   u8 no_autoconfig = 0;
9940   u8 no_onlink = 0;
9941   u8 is_no = 0;
9942   u32 val_lifetime = 0;
9943   u32 pref_lifetime = 0;
9944   int ret;
9945
9946   /* Parse args required to build the message */
9947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9948     {
9949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9950         sw_if_index_set = 1;
9951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9952         sw_if_index_set = 1;
9953       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9954         v6_address_set = 1;
9955       else if (unformat (i, "val_life %d", &val_lifetime))
9956         ;
9957       else if (unformat (i, "pref_life %d", &pref_lifetime))
9958         ;
9959       else if (unformat (i, "def"))
9960         use_default = 1;
9961       else if (unformat (i, "noadv"))
9962         no_advertise = 1;
9963       else if (unformat (i, "offl"))
9964         off_link = 1;
9965       else if (unformat (i, "noauto"))
9966         no_autoconfig = 1;
9967       else if (unformat (i, "nolink"))
9968         no_onlink = 1;
9969       else if (unformat (i, "isno"))
9970         is_no = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index_set == 0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983   if (!v6_address_set)
9984     {
9985       errmsg ("no address set");
9986       return -99;
9987     }
9988
9989   /* Construct the API message */
9990   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9991
9992   mp->sw_if_index = ntohl (sw_if_index);
9993   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9994   mp->use_default = use_default;
9995   mp->no_advertise = no_advertise;
9996   mp->off_link = off_link;
9997   mp->no_autoconfig = no_autoconfig;
9998   mp->no_onlink = no_onlink;
9999   mp->is_no = is_no;
10000   mp->val_lifetime = ntohl (val_lifetime);
10001   mp->pref_lifetime = ntohl (pref_lifetime);
10002
10003   /* send it... */
10004   S (mp);
10005
10006   /* Wait for a reply, return good/bad news  */
10007   W (ret);
10008   return ret;
10009 }
10010
10011 static int
10012 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10013 {
10014   unformat_input_t *i = vam->input;
10015   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10016   u32 sw_if_index;
10017   u8 sw_if_index_set = 0;
10018   u8 suppress = 0;
10019   u8 managed = 0;
10020   u8 other = 0;
10021   u8 ll_option = 0;
10022   u8 send_unicast = 0;
10023   u8 cease = 0;
10024   u8 is_no = 0;
10025   u8 default_router = 0;
10026   u32 max_interval = 0;
10027   u32 min_interval = 0;
10028   u32 lifetime = 0;
10029   u32 initial_count = 0;
10030   u32 initial_interval = 0;
10031   int ret;
10032
10033
10034   /* Parse args required to build the message */
10035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10036     {
10037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10038         sw_if_index_set = 1;
10039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10040         sw_if_index_set = 1;
10041       else if (unformat (i, "maxint %d", &max_interval))
10042         ;
10043       else if (unformat (i, "minint %d", &min_interval))
10044         ;
10045       else if (unformat (i, "life %d", &lifetime))
10046         ;
10047       else if (unformat (i, "count %d", &initial_count))
10048         ;
10049       else if (unformat (i, "interval %d", &initial_interval))
10050         ;
10051       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10052         suppress = 1;
10053       else if (unformat (i, "managed"))
10054         managed = 1;
10055       else if (unformat (i, "other"))
10056         other = 1;
10057       else if (unformat (i, "ll"))
10058         ll_option = 1;
10059       else if (unformat (i, "send"))
10060         send_unicast = 1;
10061       else if (unformat (i, "cease"))
10062         cease = 1;
10063       else if (unformat (i, "isno"))
10064         is_no = 1;
10065       else if (unformat (i, "def"))
10066         default_router = 1;
10067       else
10068         {
10069           clib_warning ("parse error '%U'", format_unformat_error, i);
10070           return -99;
10071         }
10072     }
10073
10074   if (sw_if_index_set == 0)
10075     {
10076       errmsg ("missing interface name or sw_if_index");
10077       return -99;
10078     }
10079
10080   /* Construct the API message */
10081   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10082
10083   mp->sw_if_index = ntohl (sw_if_index);
10084   mp->max_interval = ntohl (max_interval);
10085   mp->min_interval = ntohl (min_interval);
10086   mp->lifetime = ntohl (lifetime);
10087   mp->initial_count = ntohl (initial_count);
10088   mp->initial_interval = ntohl (initial_interval);
10089   mp->suppress = suppress;
10090   mp->managed = managed;
10091   mp->other = other;
10092   mp->ll_option = ll_option;
10093   mp->send_unicast = send_unicast;
10094   mp->cease = cease;
10095   mp->is_no = is_no;
10096   mp->default_router = default_router;
10097
10098   /* send it... */
10099   S (mp);
10100
10101   /* Wait for a reply, return good/bad news  */
10102   W (ret);
10103   return ret;
10104 }
10105
10106 static int
10107 api_set_arp_neighbor_limit (vat_main_t * vam)
10108 {
10109   unformat_input_t *i = vam->input;
10110   vl_api_set_arp_neighbor_limit_t *mp;
10111   u32 arp_nbr_limit;
10112   u8 limit_set = 0;
10113   u8 is_ipv6 = 0;
10114   int ret;
10115
10116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10117     {
10118       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10119         limit_set = 1;
10120       else if (unformat (i, "ipv6"))
10121         is_ipv6 = 1;
10122       else
10123         {
10124           clib_warning ("parse error '%U'", format_unformat_error, i);
10125           return -99;
10126         }
10127     }
10128
10129   if (limit_set == 0)
10130     {
10131       errmsg ("missing limit value");
10132       return -99;
10133     }
10134
10135   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10136
10137   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10138   mp->is_ipv6 = is_ipv6;
10139
10140   S (mp);
10141   W (ret);
10142   return ret;
10143 }
10144
10145 static int
10146 api_l2_patch_add_del (vat_main_t * vam)
10147 {
10148   unformat_input_t *i = vam->input;
10149   vl_api_l2_patch_add_del_t *mp;
10150   u32 rx_sw_if_index;
10151   u8 rx_sw_if_index_set = 0;
10152   u32 tx_sw_if_index;
10153   u8 tx_sw_if_index_set = 0;
10154   u8 is_add = 1;
10155   int ret;
10156
10157   /* Parse args required to build the message */
10158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159     {
10160       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10161         rx_sw_if_index_set = 1;
10162       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10163         tx_sw_if_index_set = 1;
10164       else if (unformat (i, "rx"))
10165         {
10166           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10167             {
10168               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10169                             &rx_sw_if_index))
10170                 rx_sw_if_index_set = 1;
10171             }
10172           else
10173             break;
10174         }
10175       else if (unformat (i, "tx"))
10176         {
10177           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10178             {
10179               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10180                             &tx_sw_if_index))
10181                 tx_sw_if_index_set = 1;
10182             }
10183           else
10184             break;
10185         }
10186       else if (unformat (i, "del"))
10187         is_add = 0;
10188       else
10189         break;
10190     }
10191
10192   if (rx_sw_if_index_set == 0)
10193     {
10194       errmsg ("missing rx interface name or rx_sw_if_index");
10195       return -99;
10196     }
10197
10198   if (tx_sw_if_index_set == 0)
10199     {
10200       errmsg ("missing tx interface name or tx_sw_if_index");
10201       return -99;
10202     }
10203
10204   M (L2_PATCH_ADD_DEL, mp);
10205
10206   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10207   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10208   mp->is_add = is_add;
10209
10210   S (mp);
10211   W (ret);
10212   return ret;
10213 }
10214
10215 u8 is_del;
10216 u8 localsid_addr[16];
10217 u8 end_psp;
10218 u8 behavior;
10219 u32 sw_if_index;
10220 u32 vlan_index;
10221 u32 fib_table;
10222 u8 nh_addr[16];
10223
10224 static int
10225 api_sr_localsid_add_del (vat_main_t * vam)
10226 {
10227   unformat_input_t *i = vam->input;
10228   vl_api_sr_localsid_add_del_t *mp;
10229
10230   u8 is_del;
10231   ip6_address_t localsid;
10232   u8 end_psp = 0;
10233   u8 behavior = ~0;
10234   u32 sw_if_index;
10235   u32 fib_table = ~(u32) 0;
10236   ip6_address_t nh_addr6;
10237   ip4_address_t nh_addr4;
10238   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10239   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10240
10241   bool nexthop_set = 0;
10242
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "del"))
10248         is_del = 1;
10249       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10250       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10251         nexthop_set = 1;
10252       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10253         nexthop_set = 1;
10254       else if (unformat (i, "behavior %u", &behavior));
10255       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10256       else if (unformat (i, "fib-table %u", &fib_table));
10257       else if (unformat (i, "end.psp %u", &behavior));
10258       else
10259         break;
10260     }
10261
10262   M (SR_LOCALSID_ADD_DEL, mp);
10263
10264   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10265   if (nexthop_set)
10266     {
10267       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10268       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10269     }
10270   mp->behavior = behavior;
10271   mp->sw_if_index = ntohl (sw_if_index);
10272   mp->fib_table = ntohl (fib_table);
10273   mp->end_psp = end_psp;
10274   mp->is_del = is_del;
10275
10276   S (mp);
10277   W (ret);
10278   return ret;
10279 }
10280
10281 static int
10282 api_ioam_enable (vat_main_t * vam)
10283 {
10284   unformat_input_t *input = vam->input;
10285   vl_api_ioam_enable_t *mp;
10286   u32 id = 0;
10287   int has_trace_option = 0;
10288   int has_pot_option = 0;
10289   int has_seqno_option = 0;
10290   int has_analyse_option = 0;
10291   int ret;
10292
10293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10294     {
10295       if (unformat (input, "trace"))
10296         has_trace_option = 1;
10297       else if (unformat (input, "pot"))
10298         has_pot_option = 1;
10299       else if (unformat (input, "seqno"))
10300         has_seqno_option = 1;
10301       else if (unformat (input, "analyse"))
10302         has_analyse_option = 1;
10303       else
10304         break;
10305     }
10306   M (IOAM_ENABLE, mp);
10307   mp->id = htons (id);
10308   mp->seqno = has_seqno_option;
10309   mp->analyse = has_analyse_option;
10310   mp->pot_enable = has_pot_option;
10311   mp->trace_enable = has_trace_option;
10312
10313   S (mp);
10314   W (ret);
10315   return ret;
10316 }
10317
10318
10319 static int
10320 api_ioam_disable (vat_main_t * vam)
10321 {
10322   vl_api_ioam_disable_t *mp;
10323   int ret;
10324
10325   M (IOAM_DISABLE, mp);
10326   S (mp);
10327   W (ret);
10328   return ret;
10329 }
10330
10331 #define foreach_tcp_proto_field                 \
10332 _(src_port)                                     \
10333 _(dst_port)
10334
10335 #define foreach_udp_proto_field                 \
10336 _(src_port)                                     \
10337 _(dst_port)
10338
10339 #define foreach_ip4_proto_field                 \
10340 _(src_address)                                  \
10341 _(dst_address)                                  \
10342 _(tos)                                          \
10343 _(length)                                       \
10344 _(fragment_id)                                  \
10345 _(ttl)                                          \
10346 _(protocol)                                     \
10347 _(checksum)
10348
10349 typedef struct
10350 {
10351   u16 src_port, dst_port;
10352 } tcpudp_header_t;
10353
10354 #if VPP_API_TEST_BUILTIN == 0
10355 uword
10356 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10357 {
10358   u8 **maskp = va_arg (*args, u8 **);
10359   u8 *mask = 0;
10360   u8 found_something = 0;
10361   tcp_header_t *tcp;
10362
10363 #define _(a) u8 a=0;
10364   foreach_tcp_proto_field;
10365 #undef _
10366
10367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10368     {
10369       if (0);
10370 #define _(a) else if (unformat (input, #a)) a=1;
10371       foreach_tcp_proto_field
10372 #undef _
10373         else
10374         break;
10375     }
10376
10377 #define _(a) found_something += a;
10378   foreach_tcp_proto_field;
10379 #undef _
10380
10381   if (found_something == 0)
10382     return 0;
10383
10384   vec_validate (mask, sizeof (*tcp) - 1);
10385
10386   tcp = (tcp_header_t *) mask;
10387
10388 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10389   foreach_tcp_proto_field;
10390 #undef _
10391
10392   *maskp = mask;
10393   return 1;
10394 }
10395
10396 uword
10397 unformat_udp_mask (unformat_input_t * input, va_list * args)
10398 {
10399   u8 **maskp = va_arg (*args, u8 **);
10400   u8 *mask = 0;
10401   u8 found_something = 0;
10402   udp_header_t *udp;
10403
10404 #define _(a) u8 a=0;
10405   foreach_udp_proto_field;
10406 #undef _
10407
10408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (0);
10411 #define _(a) else if (unformat (input, #a)) a=1;
10412       foreach_udp_proto_field
10413 #undef _
10414         else
10415         break;
10416     }
10417
10418 #define _(a) found_something += a;
10419   foreach_udp_proto_field;
10420 #undef _
10421
10422   if (found_something == 0)
10423     return 0;
10424
10425   vec_validate (mask, sizeof (*udp) - 1);
10426
10427   udp = (udp_header_t *) mask;
10428
10429 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10430   foreach_udp_proto_field;
10431 #undef _
10432
10433   *maskp = mask;
10434   return 1;
10435 }
10436
10437 uword
10438 unformat_l4_mask (unformat_input_t * input, va_list * args)
10439 {
10440   u8 **maskp = va_arg (*args, u8 **);
10441   u16 src_port = 0, dst_port = 0;
10442   tcpudp_header_t *tcpudp;
10443
10444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10447         return 1;
10448       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10449         return 1;
10450       else if (unformat (input, "src_port"))
10451         src_port = 0xFFFF;
10452       else if (unformat (input, "dst_port"))
10453         dst_port = 0xFFFF;
10454       else
10455         return 0;
10456     }
10457
10458   if (!src_port && !dst_port)
10459     return 0;
10460
10461   u8 *mask = 0;
10462   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10463
10464   tcpudp = (tcpudp_header_t *) mask;
10465   tcpudp->src_port = src_port;
10466   tcpudp->dst_port = dst_port;
10467
10468   *maskp = mask;
10469
10470   return 1;
10471 }
10472
10473 uword
10474 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10475 {
10476   u8 **maskp = va_arg (*args, u8 **);
10477   u8 *mask = 0;
10478   u8 found_something = 0;
10479   ip4_header_t *ip;
10480
10481 #define _(a) u8 a=0;
10482   foreach_ip4_proto_field;
10483 #undef _
10484   u8 version = 0;
10485   u8 hdr_length = 0;
10486
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (unformat (input, "version"))
10491         version = 1;
10492       else if (unformat (input, "hdr_length"))
10493         hdr_length = 1;
10494       else if (unformat (input, "src"))
10495         src_address = 1;
10496       else if (unformat (input, "dst"))
10497         dst_address = 1;
10498       else if (unformat (input, "proto"))
10499         protocol = 1;
10500
10501 #define _(a) else if (unformat (input, #a)) a=1;
10502       foreach_ip4_proto_field
10503 #undef _
10504         else
10505         break;
10506     }
10507
10508 #define _(a) found_something += a;
10509   foreach_ip4_proto_field;
10510 #undef _
10511
10512   if (found_something == 0)
10513     return 0;
10514
10515   vec_validate (mask, sizeof (*ip) - 1);
10516
10517   ip = (ip4_header_t *) mask;
10518
10519 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10520   foreach_ip4_proto_field;
10521 #undef _
10522
10523   ip->ip_version_and_header_length = 0;
10524
10525   if (version)
10526     ip->ip_version_and_header_length |= 0xF0;
10527
10528   if (hdr_length)
10529     ip->ip_version_and_header_length |= 0x0F;
10530
10531   *maskp = mask;
10532   return 1;
10533 }
10534
10535 #define foreach_ip6_proto_field                 \
10536 _(src_address)                                  \
10537 _(dst_address)                                  \
10538 _(payload_length)                               \
10539 _(hop_limit)                                    \
10540 _(protocol)
10541
10542 uword
10543 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10544 {
10545   u8 **maskp = va_arg (*args, u8 **);
10546   u8 *mask = 0;
10547   u8 found_something = 0;
10548   ip6_header_t *ip;
10549   u32 ip_version_traffic_class_and_flow_label;
10550
10551 #define _(a) u8 a=0;
10552   foreach_ip6_proto_field;
10553 #undef _
10554   u8 version = 0;
10555   u8 traffic_class = 0;
10556   u8 flow_label = 0;
10557
10558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (unformat (input, "version"))
10561         version = 1;
10562       else if (unformat (input, "traffic-class"))
10563         traffic_class = 1;
10564       else if (unformat (input, "flow-label"))
10565         flow_label = 1;
10566       else if (unformat (input, "src"))
10567         src_address = 1;
10568       else if (unformat (input, "dst"))
10569         dst_address = 1;
10570       else if (unformat (input, "proto"))
10571         protocol = 1;
10572
10573 #define _(a) else if (unformat (input, #a)) a=1;
10574       foreach_ip6_proto_field
10575 #undef _
10576         else
10577         break;
10578     }
10579
10580 #define _(a) found_something += a;
10581   foreach_ip6_proto_field;
10582 #undef _
10583
10584   if (found_something == 0)
10585     return 0;
10586
10587   vec_validate (mask, sizeof (*ip) - 1);
10588
10589   ip = (ip6_header_t *) mask;
10590
10591 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10592   foreach_ip6_proto_field;
10593 #undef _
10594
10595   ip_version_traffic_class_and_flow_label = 0;
10596
10597   if (version)
10598     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10599
10600   if (traffic_class)
10601     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10602
10603   if (flow_label)
10604     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10605
10606   ip->ip_version_traffic_class_and_flow_label =
10607     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10608
10609   *maskp = mask;
10610   return 1;
10611 }
10612
10613 uword
10614 unformat_l3_mask (unformat_input_t * input, va_list * args)
10615 {
10616   u8 **maskp = va_arg (*args, u8 **);
10617
10618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10619     {
10620       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10621         return 1;
10622       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10623         return 1;
10624       else
10625         break;
10626     }
10627   return 0;
10628 }
10629
10630 uword
10631 unformat_l2_mask (unformat_input_t * input, va_list * args)
10632 {
10633   u8 **maskp = va_arg (*args, u8 **);
10634   u8 *mask = 0;
10635   u8 src = 0;
10636   u8 dst = 0;
10637   u8 proto = 0;
10638   u8 tag1 = 0;
10639   u8 tag2 = 0;
10640   u8 ignore_tag1 = 0;
10641   u8 ignore_tag2 = 0;
10642   u8 cos1 = 0;
10643   u8 cos2 = 0;
10644   u8 dot1q = 0;
10645   u8 dot1ad = 0;
10646   int len = 14;
10647
10648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10649     {
10650       if (unformat (input, "src"))
10651         src = 1;
10652       else if (unformat (input, "dst"))
10653         dst = 1;
10654       else if (unformat (input, "proto"))
10655         proto = 1;
10656       else if (unformat (input, "tag1"))
10657         tag1 = 1;
10658       else if (unformat (input, "tag2"))
10659         tag2 = 1;
10660       else if (unformat (input, "ignore-tag1"))
10661         ignore_tag1 = 1;
10662       else if (unformat (input, "ignore-tag2"))
10663         ignore_tag2 = 1;
10664       else if (unformat (input, "cos1"))
10665         cos1 = 1;
10666       else if (unformat (input, "cos2"))
10667         cos2 = 1;
10668       else if (unformat (input, "dot1q"))
10669         dot1q = 1;
10670       else if (unformat (input, "dot1ad"))
10671         dot1ad = 1;
10672       else
10673         break;
10674     }
10675   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10676        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10677     return 0;
10678
10679   if (tag1 || ignore_tag1 || cos1 || dot1q)
10680     len = 18;
10681   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10682     len = 22;
10683
10684   vec_validate (mask, len - 1);
10685
10686   if (dst)
10687     clib_memset (mask, 0xff, 6);
10688
10689   if (src)
10690     clib_memset (mask + 6, 0xff, 6);
10691
10692   if (tag2 || dot1ad)
10693     {
10694       /* inner vlan tag */
10695       if (tag2)
10696         {
10697           mask[19] = 0xff;
10698           mask[18] = 0x0f;
10699         }
10700       if (cos2)
10701         mask[18] |= 0xe0;
10702       if (proto)
10703         mask[21] = mask[20] = 0xff;
10704       if (tag1)
10705         {
10706           mask[15] = 0xff;
10707           mask[14] = 0x0f;
10708         }
10709       if (cos1)
10710         mask[14] |= 0xe0;
10711       *maskp = mask;
10712       return 1;
10713     }
10714   if (tag1 | dot1q)
10715     {
10716       if (tag1)
10717         {
10718           mask[15] = 0xff;
10719           mask[14] = 0x0f;
10720         }
10721       if (cos1)
10722         mask[14] |= 0xe0;
10723       if (proto)
10724         mask[16] = mask[17] = 0xff;
10725
10726       *maskp = mask;
10727       return 1;
10728     }
10729   if (cos2)
10730     mask[18] |= 0xe0;
10731   if (cos1)
10732     mask[14] |= 0xe0;
10733   if (proto)
10734     mask[12] = mask[13] = 0xff;
10735
10736   *maskp = mask;
10737   return 1;
10738 }
10739
10740 uword
10741 unformat_classify_mask (unformat_input_t * input, va_list * args)
10742 {
10743   u8 **maskp = va_arg (*args, u8 **);
10744   u32 *skipp = va_arg (*args, u32 *);
10745   u32 *matchp = va_arg (*args, u32 *);
10746   u32 match;
10747   u8 *mask = 0;
10748   u8 *l2 = 0;
10749   u8 *l3 = 0;
10750   u8 *l4 = 0;
10751   int i;
10752
10753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10756         ;
10757       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10758         ;
10759       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10760         ;
10761       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10762         ;
10763       else
10764         break;
10765     }
10766
10767   if (l4 && !l3)
10768     {
10769       vec_free (mask);
10770       vec_free (l2);
10771       vec_free (l4);
10772       return 0;
10773     }
10774
10775   if (mask || l2 || l3 || l4)
10776     {
10777       if (l2 || l3 || l4)
10778         {
10779           /* "With a free Ethernet header in every package" */
10780           if (l2 == 0)
10781             vec_validate (l2, 13);
10782           mask = l2;
10783           if (vec_len (l3))
10784             {
10785               vec_append (mask, l3);
10786               vec_free (l3);
10787             }
10788           if (vec_len (l4))
10789             {
10790               vec_append (mask, l4);
10791               vec_free (l4);
10792             }
10793         }
10794
10795       /* Scan forward looking for the first significant mask octet */
10796       for (i = 0; i < vec_len (mask); i++)
10797         if (mask[i])
10798           break;
10799
10800       /* compute (skip, match) params */
10801       *skipp = i / sizeof (u32x4);
10802       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10803
10804       /* Pad mask to an even multiple of the vector size */
10805       while (vec_len (mask) % sizeof (u32x4))
10806         vec_add1 (mask, 0);
10807
10808       match = vec_len (mask) / sizeof (u32x4);
10809
10810       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10811         {
10812           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10813           if (*tmp || *(tmp + 1))
10814             break;
10815           match--;
10816         }
10817       if (match == 0)
10818         clib_warning ("BUG: match 0");
10819
10820       _vec_len (mask) = match * sizeof (u32x4);
10821
10822       *matchp = match;
10823       *maskp = mask;
10824
10825       return 1;
10826     }
10827
10828   return 0;
10829 }
10830 #endif /* VPP_API_TEST_BUILTIN */
10831
10832 #define foreach_l2_next                         \
10833 _(drop, DROP)                                   \
10834 _(ethernet, ETHERNET_INPUT)                     \
10835 _(ip4, IP4_INPUT)                               \
10836 _(ip6, IP6_INPUT)
10837
10838 uword
10839 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10840 {
10841   u32 *miss_next_indexp = va_arg (*args, u32 *);
10842   u32 next_index = 0;
10843   u32 tmp;
10844
10845 #define _(n,N) \
10846   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10847   foreach_l2_next;
10848 #undef _
10849
10850   if (unformat (input, "%d", &tmp))
10851     {
10852       next_index = tmp;
10853       goto out;
10854     }
10855
10856   return 0;
10857
10858 out:
10859   *miss_next_indexp = next_index;
10860   return 1;
10861 }
10862
10863 #define foreach_ip_next                         \
10864 _(drop, DROP)                                   \
10865 _(local, LOCAL)                                 \
10866 _(rewrite, REWRITE)
10867
10868 uword
10869 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10870 {
10871   u32 *miss_next_indexp = va_arg (*args, u32 *);
10872   u32 next_index = 0;
10873   u32 tmp;
10874
10875 #define _(n,N) \
10876   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10877   foreach_ip_next;
10878 #undef _
10879
10880   if (unformat (input, "%d", &tmp))
10881     {
10882       next_index = tmp;
10883       goto out;
10884     }
10885
10886   return 0;
10887
10888 out:
10889   *miss_next_indexp = next_index;
10890   return 1;
10891 }
10892
10893 #define foreach_acl_next                        \
10894 _(deny, DENY)
10895
10896 uword
10897 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10898 {
10899   u32 *miss_next_indexp = va_arg (*args, u32 *);
10900   u32 next_index = 0;
10901   u32 tmp;
10902
10903 #define _(n,N) \
10904   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10905   foreach_acl_next;
10906 #undef _
10907
10908   if (unformat (input, "permit"))
10909     {
10910       next_index = ~0;
10911       goto out;
10912     }
10913   else if (unformat (input, "%d", &tmp))
10914     {
10915       next_index = tmp;
10916       goto out;
10917     }
10918
10919   return 0;
10920
10921 out:
10922   *miss_next_indexp = next_index;
10923   return 1;
10924 }
10925
10926 uword
10927 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10928 {
10929   u32 *r = va_arg (*args, u32 *);
10930
10931   if (unformat (input, "conform-color"))
10932     *r = POLICE_CONFORM;
10933   else if (unformat (input, "exceed-color"))
10934     *r = POLICE_EXCEED;
10935   else
10936     return 0;
10937
10938   return 1;
10939 }
10940
10941 static int
10942 api_classify_add_del_table (vat_main_t * vam)
10943 {
10944   unformat_input_t *i = vam->input;
10945   vl_api_classify_add_del_table_t *mp;
10946
10947   u32 nbuckets = 2;
10948   u32 skip = ~0;
10949   u32 match = ~0;
10950   int is_add = 1;
10951   int del_chain = 0;
10952   u32 table_index = ~0;
10953   u32 next_table_index = ~0;
10954   u32 miss_next_index = ~0;
10955   u32 memory_size = 32 << 20;
10956   u8 *mask = 0;
10957   u32 current_data_flag = 0;
10958   int current_data_offset = 0;
10959   int ret;
10960
10961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10962     {
10963       if (unformat (i, "del"))
10964         is_add = 0;
10965       else if (unformat (i, "del-chain"))
10966         {
10967           is_add = 0;
10968           del_chain = 1;
10969         }
10970       else if (unformat (i, "buckets %d", &nbuckets))
10971         ;
10972       else if (unformat (i, "memory_size %d", &memory_size))
10973         ;
10974       else if (unformat (i, "skip %d", &skip))
10975         ;
10976       else if (unformat (i, "match %d", &match))
10977         ;
10978       else if (unformat (i, "table %d", &table_index))
10979         ;
10980       else if (unformat (i, "mask %U", unformat_classify_mask,
10981                          &mask, &skip, &match))
10982         ;
10983       else if (unformat (i, "next-table %d", &next_table_index))
10984         ;
10985       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10986                          &miss_next_index))
10987         ;
10988       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10989                          &miss_next_index))
10990         ;
10991       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10992                          &miss_next_index))
10993         ;
10994       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10995         ;
10996       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10997         ;
10998       else
10999         break;
11000     }
11001
11002   if (is_add && mask == 0)
11003     {
11004       errmsg ("Mask required");
11005       return -99;
11006     }
11007
11008   if (is_add && skip == ~0)
11009     {
11010       errmsg ("skip count required");
11011       return -99;
11012     }
11013
11014   if (is_add && match == ~0)
11015     {
11016       errmsg ("match count required");
11017       return -99;
11018     }
11019
11020   if (!is_add && table_index == ~0)
11021     {
11022       errmsg ("table index required for delete");
11023       return -99;
11024     }
11025
11026   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11027
11028   mp->is_add = is_add;
11029   mp->del_chain = del_chain;
11030   mp->table_index = ntohl (table_index);
11031   mp->nbuckets = ntohl (nbuckets);
11032   mp->memory_size = ntohl (memory_size);
11033   mp->skip_n_vectors = ntohl (skip);
11034   mp->match_n_vectors = ntohl (match);
11035   mp->next_table_index = ntohl (next_table_index);
11036   mp->miss_next_index = ntohl (miss_next_index);
11037   mp->current_data_flag = ntohl (current_data_flag);
11038   mp->current_data_offset = ntohl (current_data_offset);
11039   mp->mask_len = ntohl (vec_len (mask));
11040   clib_memcpy (mp->mask, mask, vec_len (mask));
11041
11042   vec_free (mask);
11043
11044   S (mp);
11045   W (ret);
11046   return ret;
11047 }
11048
11049 #if VPP_API_TEST_BUILTIN == 0
11050 uword
11051 unformat_l4_match (unformat_input_t * input, va_list * args)
11052 {
11053   u8 **matchp = va_arg (*args, u8 **);
11054
11055   u8 *proto_header = 0;
11056   int src_port = 0;
11057   int dst_port = 0;
11058
11059   tcpudp_header_t h;
11060
11061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11062     {
11063       if (unformat (input, "src_port %d", &src_port))
11064         ;
11065       else if (unformat (input, "dst_port %d", &dst_port))
11066         ;
11067       else
11068         return 0;
11069     }
11070
11071   h.src_port = clib_host_to_net_u16 (src_port);
11072   h.dst_port = clib_host_to_net_u16 (dst_port);
11073   vec_validate (proto_header, sizeof (h) - 1);
11074   memcpy (proto_header, &h, sizeof (h));
11075
11076   *matchp = proto_header;
11077
11078   return 1;
11079 }
11080
11081 uword
11082 unformat_ip4_match (unformat_input_t * input, va_list * args)
11083 {
11084   u8 **matchp = va_arg (*args, u8 **);
11085   u8 *match = 0;
11086   ip4_header_t *ip;
11087   int version = 0;
11088   u32 version_val;
11089   int hdr_length = 0;
11090   u32 hdr_length_val;
11091   int src = 0, dst = 0;
11092   ip4_address_t src_val, dst_val;
11093   int proto = 0;
11094   u32 proto_val;
11095   int tos = 0;
11096   u32 tos_val;
11097   int length = 0;
11098   u32 length_val;
11099   int fragment_id = 0;
11100   u32 fragment_id_val;
11101   int ttl = 0;
11102   int ttl_val;
11103   int checksum = 0;
11104   u32 checksum_val;
11105
11106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11107     {
11108       if (unformat (input, "version %d", &version_val))
11109         version = 1;
11110       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11111         hdr_length = 1;
11112       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11113         src = 1;
11114       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11115         dst = 1;
11116       else if (unformat (input, "proto %d", &proto_val))
11117         proto = 1;
11118       else if (unformat (input, "tos %d", &tos_val))
11119         tos = 1;
11120       else if (unformat (input, "length %d", &length_val))
11121         length = 1;
11122       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11123         fragment_id = 1;
11124       else if (unformat (input, "ttl %d", &ttl_val))
11125         ttl = 1;
11126       else if (unformat (input, "checksum %d", &checksum_val))
11127         checksum = 1;
11128       else
11129         break;
11130     }
11131
11132   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11133       + ttl + checksum == 0)
11134     return 0;
11135
11136   /*
11137    * Aligned because we use the real comparison functions
11138    */
11139   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11140
11141   ip = (ip4_header_t *) match;
11142
11143   /* These are realistically matched in practice */
11144   if (src)
11145     ip->src_address.as_u32 = src_val.as_u32;
11146
11147   if (dst)
11148     ip->dst_address.as_u32 = dst_val.as_u32;
11149
11150   if (proto)
11151     ip->protocol = proto_val;
11152
11153
11154   /* These are not, but they're included for completeness */
11155   if (version)
11156     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11157
11158   if (hdr_length)
11159     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11160
11161   if (tos)
11162     ip->tos = tos_val;
11163
11164   if (length)
11165     ip->length = clib_host_to_net_u16 (length_val);
11166
11167   if (ttl)
11168     ip->ttl = ttl_val;
11169
11170   if (checksum)
11171     ip->checksum = clib_host_to_net_u16 (checksum_val);
11172
11173   *matchp = match;
11174   return 1;
11175 }
11176
11177 uword
11178 unformat_ip6_match (unformat_input_t * input, va_list * args)
11179 {
11180   u8 **matchp = va_arg (*args, u8 **);
11181   u8 *match = 0;
11182   ip6_header_t *ip;
11183   int version = 0;
11184   u32 version_val;
11185   u8 traffic_class = 0;
11186   u32 traffic_class_val = 0;
11187   u8 flow_label = 0;
11188   u8 flow_label_val;
11189   int src = 0, dst = 0;
11190   ip6_address_t src_val, dst_val;
11191   int proto = 0;
11192   u32 proto_val;
11193   int payload_length = 0;
11194   u32 payload_length_val;
11195   int hop_limit = 0;
11196   int hop_limit_val;
11197   u32 ip_version_traffic_class_and_flow_label;
11198
11199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11200     {
11201       if (unformat (input, "version %d", &version_val))
11202         version = 1;
11203       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11204         traffic_class = 1;
11205       else if (unformat (input, "flow_label %d", &flow_label_val))
11206         flow_label = 1;
11207       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11208         src = 1;
11209       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11210         dst = 1;
11211       else if (unformat (input, "proto %d", &proto_val))
11212         proto = 1;
11213       else if (unformat (input, "payload_length %d", &payload_length_val))
11214         payload_length = 1;
11215       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11216         hop_limit = 1;
11217       else
11218         break;
11219     }
11220
11221   if (version + traffic_class + flow_label + src + dst + proto +
11222       payload_length + hop_limit == 0)
11223     return 0;
11224
11225   /*
11226    * Aligned because we use the real comparison functions
11227    */
11228   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11229
11230   ip = (ip6_header_t *) match;
11231
11232   if (src)
11233     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11234
11235   if (dst)
11236     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11237
11238   if (proto)
11239     ip->protocol = proto_val;
11240
11241   ip_version_traffic_class_and_flow_label = 0;
11242
11243   if (version)
11244     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11245
11246   if (traffic_class)
11247     ip_version_traffic_class_and_flow_label |=
11248       (traffic_class_val & 0xFF) << 20;
11249
11250   if (flow_label)
11251     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11252
11253   ip->ip_version_traffic_class_and_flow_label =
11254     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11255
11256   if (payload_length)
11257     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11258
11259   if (hop_limit)
11260     ip->hop_limit = hop_limit_val;
11261
11262   *matchp = match;
11263   return 1;
11264 }
11265
11266 uword
11267 unformat_l3_match (unformat_input_t * input, va_list * args)
11268 {
11269   u8 **matchp = va_arg (*args, u8 **);
11270
11271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11272     {
11273       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11274         return 1;
11275       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11276         return 1;
11277       else
11278         break;
11279     }
11280   return 0;
11281 }
11282
11283 uword
11284 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11285 {
11286   u8 *tagp = va_arg (*args, u8 *);
11287   u32 tag;
11288
11289   if (unformat (input, "%d", &tag))
11290     {
11291       tagp[0] = (tag >> 8) & 0x0F;
11292       tagp[1] = tag & 0xFF;
11293       return 1;
11294     }
11295
11296   return 0;
11297 }
11298
11299 uword
11300 unformat_l2_match (unformat_input_t * input, va_list * args)
11301 {
11302   u8 **matchp = va_arg (*args, u8 **);
11303   u8 *match = 0;
11304   u8 src = 0;
11305   u8 src_val[6];
11306   u8 dst = 0;
11307   u8 dst_val[6];
11308   u8 proto = 0;
11309   u16 proto_val;
11310   u8 tag1 = 0;
11311   u8 tag1_val[2];
11312   u8 tag2 = 0;
11313   u8 tag2_val[2];
11314   int len = 14;
11315   u8 ignore_tag1 = 0;
11316   u8 ignore_tag2 = 0;
11317   u8 cos1 = 0;
11318   u8 cos2 = 0;
11319   u32 cos1_val = 0;
11320   u32 cos2_val = 0;
11321
11322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11323     {
11324       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11325         src = 1;
11326       else
11327         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11328         dst = 1;
11329       else if (unformat (input, "proto %U",
11330                          unformat_ethernet_type_host_byte_order, &proto_val))
11331         proto = 1;
11332       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11333         tag1 = 1;
11334       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11335         tag2 = 1;
11336       else if (unformat (input, "ignore-tag1"))
11337         ignore_tag1 = 1;
11338       else if (unformat (input, "ignore-tag2"))
11339         ignore_tag2 = 1;
11340       else if (unformat (input, "cos1 %d", &cos1_val))
11341         cos1 = 1;
11342       else if (unformat (input, "cos2 %d", &cos2_val))
11343         cos2 = 1;
11344       else
11345         break;
11346     }
11347   if ((src + dst + proto + tag1 + tag2 +
11348        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11349     return 0;
11350
11351   if (tag1 || ignore_tag1 || cos1)
11352     len = 18;
11353   if (tag2 || ignore_tag2 || cos2)
11354     len = 22;
11355
11356   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11357
11358   if (dst)
11359     clib_memcpy (match, dst_val, 6);
11360
11361   if (src)
11362     clib_memcpy (match + 6, src_val, 6);
11363
11364   if (tag2)
11365     {
11366       /* inner vlan tag */
11367       match[19] = tag2_val[1];
11368       match[18] = tag2_val[0];
11369       if (cos2)
11370         match[18] |= (cos2_val & 0x7) << 5;
11371       if (proto)
11372         {
11373           match[21] = proto_val & 0xff;
11374           match[20] = proto_val >> 8;
11375         }
11376       if (tag1)
11377         {
11378           match[15] = tag1_val[1];
11379           match[14] = tag1_val[0];
11380         }
11381       if (cos1)
11382         match[14] |= (cos1_val & 0x7) << 5;
11383       *matchp = match;
11384       return 1;
11385     }
11386   if (tag1)
11387     {
11388       match[15] = tag1_val[1];
11389       match[14] = tag1_val[0];
11390       if (proto)
11391         {
11392           match[17] = proto_val & 0xff;
11393           match[16] = proto_val >> 8;
11394         }
11395       if (cos1)
11396         match[14] |= (cos1_val & 0x7) << 5;
11397
11398       *matchp = match;
11399       return 1;
11400     }
11401   if (cos2)
11402     match[18] |= (cos2_val & 0x7) << 5;
11403   if (cos1)
11404     match[14] |= (cos1_val & 0x7) << 5;
11405   if (proto)
11406     {
11407       match[13] = proto_val & 0xff;
11408       match[12] = proto_val >> 8;
11409     }
11410
11411   *matchp = match;
11412   return 1;
11413 }
11414
11415 uword
11416 unformat_qos_source (unformat_input_t * input, va_list * args)
11417 {
11418   int *qs = va_arg (*args, int *);
11419
11420   if (unformat (input, "ip"))
11421     *qs = QOS_SOURCE_IP;
11422   else if (unformat (input, "mpls"))
11423     *qs = QOS_SOURCE_MPLS;
11424   else if (unformat (input, "ext"))
11425     *qs = QOS_SOURCE_EXT;
11426   else if (unformat (input, "vlan"))
11427     *qs = QOS_SOURCE_VLAN;
11428   else
11429     return 0;
11430
11431   return 1;
11432 }
11433 #endif
11434
11435 uword
11436 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11437 {
11438   u8 **matchp = va_arg (*args, u8 **);
11439   u32 skip_n_vectors = va_arg (*args, u32);
11440   u32 match_n_vectors = va_arg (*args, u32);
11441
11442   u8 *match = 0;
11443   u8 *l2 = 0;
11444   u8 *l3 = 0;
11445   u8 *l4 = 0;
11446
11447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11448     {
11449       if (unformat (input, "hex %U", unformat_hex_string, &match))
11450         ;
11451       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11452         ;
11453       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11454         ;
11455       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11456         ;
11457       else
11458         break;
11459     }
11460
11461   if (l4 && !l3)
11462     {
11463       vec_free (match);
11464       vec_free (l2);
11465       vec_free (l4);
11466       return 0;
11467     }
11468
11469   if (match || l2 || l3 || l4)
11470     {
11471       if (l2 || l3 || l4)
11472         {
11473           /* "Win a free Ethernet header in every packet" */
11474           if (l2 == 0)
11475             vec_validate_aligned (l2, 13, sizeof (u32x4));
11476           match = l2;
11477           if (vec_len (l3))
11478             {
11479               vec_append_aligned (match, l3, sizeof (u32x4));
11480               vec_free (l3);
11481             }
11482           if (vec_len (l4))
11483             {
11484               vec_append_aligned (match, l4, sizeof (u32x4));
11485               vec_free (l4);
11486             }
11487         }
11488
11489       /* Make sure the vector is big enough even if key is all 0's */
11490       vec_validate_aligned
11491         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11492          sizeof (u32x4));
11493
11494       /* Set size, include skipped vectors */
11495       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11496
11497       *matchp = match;
11498
11499       return 1;
11500     }
11501
11502   return 0;
11503 }
11504
11505 static int
11506 api_classify_add_del_session (vat_main_t * vam)
11507 {
11508   unformat_input_t *i = vam->input;
11509   vl_api_classify_add_del_session_t *mp;
11510   int is_add = 1;
11511   u32 table_index = ~0;
11512   u32 hit_next_index = ~0;
11513   u32 opaque_index = ~0;
11514   u8 *match = 0;
11515   i32 advance = 0;
11516   u32 skip_n_vectors = 0;
11517   u32 match_n_vectors = 0;
11518   u32 action = 0;
11519   u32 metadata = 0;
11520   int ret;
11521
11522   /*
11523    * Warning: you have to supply skip_n and match_n
11524    * because the API client cant simply look at the classify
11525    * table object.
11526    */
11527
11528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11529     {
11530       if (unformat (i, "del"))
11531         is_add = 0;
11532       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11533                          &hit_next_index))
11534         ;
11535       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11536                          &hit_next_index))
11537         ;
11538       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11539                          &hit_next_index))
11540         ;
11541       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11542         ;
11543       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11544         ;
11545       else if (unformat (i, "opaque-index %d", &opaque_index))
11546         ;
11547       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11548         ;
11549       else if (unformat (i, "match_n %d", &match_n_vectors))
11550         ;
11551       else if (unformat (i, "match %U", api_unformat_classify_match,
11552                          &match, skip_n_vectors, match_n_vectors))
11553         ;
11554       else if (unformat (i, "advance %d", &advance))
11555         ;
11556       else if (unformat (i, "table-index %d", &table_index))
11557         ;
11558       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11559         action = 1;
11560       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11561         action = 2;
11562       else if (unformat (i, "action %d", &action))
11563         ;
11564       else if (unformat (i, "metadata %d", &metadata))
11565         ;
11566       else
11567         break;
11568     }
11569
11570   if (table_index == ~0)
11571     {
11572       errmsg ("Table index required");
11573       return -99;
11574     }
11575
11576   if (is_add && match == 0)
11577     {
11578       errmsg ("Match value required");
11579       return -99;
11580     }
11581
11582   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11583
11584   mp->is_add = is_add;
11585   mp->table_index = ntohl (table_index);
11586   mp->hit_next_index = ntohl (hit_next_index);
11587   mp->opaque_index = ntohl (opaque_index);
11588   mp->advance = ntohl (advance);
11589   mp->action = action;
11590   mp->metadata = ntohl (metadata);
11591   mp->match_len = ntohl (vec_len (match));
11592   clib_memcpy (mp->match, match, vec_len (match));
11593   vec_free (match);
11594
11595   S (mp);
11596   W (ret);
11597   return ret;
11598 }
11599
11600 static int
11601 api_classify_set_interface_ip_table (vat_main_t * vam)
11602 {
11603   unformat_input_t *i = vam->input;
11604   vl_api_classify_set_interface_ip_table_t *mp;
11605   u32 sw_if_index;
11606   int sw_if_index_set;
11607   u32 table_index = ~0;
11608   u8 is_ipv6 = 0;
11609   int ret;
11610
11611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11612     {
11613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11614         sw_if_index_set = 1;
11615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11616         sw_if_index_set = 1;
11617       else if (unformat (i, "table %d", &table_index))
11618         ;
11619       else
11620         {
11621           clib_warning ("parse error '%U'", format_unformat_error, i);
11622           return -99;
11623         }
11624     }
11625
11626   if (sw_if_index_set == 0)
11627     {
11628       errmsg ("missing interface name or sw_if_index");
11629       return -99;
11630     }
11631
11632
11633   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11634
11635   mp->sw_if_index = ntohl (sw_if_index);
11636   mp->table_index = ntohl (table_index);
11637   mp->is_ipv6 = is_ipv6;
11638
11639   S (mp);
11640   W (ret);
11641   return ret;
11642 }
11643
11644 static int
11645 api_classify_set_interface_l2_tables (vat_main_t * vam)
11646 {
11647   unformat_input_t *i = vam->input;
11648   vl_api_classify_set_interface_l2_tables_t *mp;
11649   u32 sw_if_index;
11650   int sw_if_index_set;
11651   u32 ip4_table_index = ~0;
11652   u32 ip6_table_index = ~0;
11653   u32 other_table_index = ~0;
11654   u32 is_input = 1;
11655   int ret;
11656
11657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11658     {
11659       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11660         sw_if_index_set = 1;
11661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11662         sw_if_index_set = 1;
11663       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11664         ;
11665       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11666         ;
11667       else if (unformat (i, "other-table %d", &other_table_index))
11668         ;
11669       else if (unformat (i, "is-input %d", &is_input))
11670         ;
11671       else
11672         {
11673           clib_warning ("parse error '%U'", format_unformat_error, i);
11674           return -99;
11675         }
11676     }
11677
11678   if (sw_if_index_set == 0)
11679     {
11680       errmsg ("missing interface name or sw_if_index");
11681       return -99;
11682     }
11683
11684
11685   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11686
11687   mp->sw_if_index = ntohl (sw_if_index);
11688   mp->ip4_table_index = ntohl (ip4_table_index);
11689   mp->ip6_table_index = ntohl (ip6_table_index);
11690   mp->other_table_index = ntohl (other_table_index);
11691   mp->is_input = (u8) is_input;
11692
11693   S (mp);
11694   W (ret);
11695   return ret;
11696 }
11697
11698 static int
11699 api_set_ipfix_exporter (vat_main_t * vam)
11700 {
11701   unformat_input_t *i = vam->input;
11702   vl_api_set_ipfix_exporter_t *mp;
11703   ip4_address_t collector_address;
11704   u8 collector_address_set = 0;
11705   u32 collector_port = ~0;
11706   ip4_address_t src_address;
11707   u8 src_address_set = 0;
11708   u32 vrf_id = ~0;
11709   u32 path_mtu = ~0;
11710   u32 template_interval = ~0;
11711   u8 udp_checksum = 0;
11712   int ret;
11713
11714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11715     {
11716       if (unformat (i, "collector_address %U", unformat_ip4_address,
11717                     &collector_address))
11718         collector_address_set = 1;
11719       else if (unformat (i, "collector_port %d", &collector_port))
11720         ;
11721       else if (unformat (i, "src_address %U", unformat_ip4_address,
11722                          &src_address))
11723         src_address_set = 1;
11724       else if (unformat (i, "vrf_id %d", &vrf_id))
11725         ;
11726       else if (unformat (i, "path_mtu %d", &path_mtu))
11727         ;
11728       else if (unformat (i, "template_interval %d", &template_interval))
11729         ;
11730       else if (unformat (i, "udp_checksum"))
11731         udp_checksum = 1;
11732       else
11733         break;
11734     }
11735
11736   if (collector_address_set == 0)
11737     {
11738       errmsg ("collector_address required");
11739       return -99;
11740     }
11741
11742   if (src_address_set == 0)
11743     {
11744       errmsg ("src_address required");
11745       return -99;
11746     }
11747
11748   M (SET_IPFIX_EXPORTER, mp);
11749
11750   memcpy (mp->collector_address, collector_address.data,
11751           sizeof (collector_address.data));
11752   mp->collector_port = htons ((u16) collector_port);
11753   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11754   mp->vrf_id = htonl (vrf_id);
11755   mp->path_mtu = htonl (path_mtu);
11756   mp->template_interval = htonl (template_interval);
11757   mp->udp_checksum = udp_checksum;
11758
11759   S (mp);
11760   W (ret);
11761   return ret;
11762 }
11763
11764 static int
11765 api_set_ipfix_classify_stream (vat_main_t * vam)
11766 {
11767   unformat_input_t *i = vam->input;
11768   vl_api_set_ipfix_classify_stream_t *mp;
11769   u32 domain_id = 0;
11770   u32 src_port = UDP_DST_PORT_ipfix;
11771   int ret;
11772
11773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11774     {
11775       if (unformat (i, "domain %d", &domain_id))
11776         ;
11777       else if (unformat (i, "src_port %d", &src_port))
11778         ;
11779       else
11780         {
11781           errmsg ("unknown input `%U'", format_unformat_error, i);
11782           return -99;
11783         }
11784     }
11785
11786   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11787
11788   mp->domain_id = htonl (domain_id);
11789   mp->src_port = htons ((u16) src_port);
11790
11791   S (mp);
11792   W (ret);
11793   return ret;
11794 }
11795
11796 static int
11797 api_ipfix_classify_table_add_del (vat_main_t * vam)
11798 {
11799   unformat_input_t *i = vam->input;
11800   vl_api_ipfix_classify_table_add_del_t *mp;
11801   int is_add = -1;
11802   u32 classify_table_index = ~0;
11803   u8 ip_version = 0;
11804   u8 transport_protocol = 255;
11805   int ret;
11806
11807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11808     {
11809       if (unformat (i, "add"))
11810         is_add = 1;
11811       else if (unformat (i, "del"))
11812         is_add = 0;
11813       else if (unformat (i, "table %d", &classify_table_index))
11814         ;
11815       else if (unformat (i, "ip4"))
11816         ip_version = 4;
11817       else if (unformat (i, "ip6"))
11818         ip_version = 6;
11819       else if (unformat (i, "tcp"))
11820         transport_protocol = 6;
11821       else if (unformat (i, "udp"))
11822         transport_protocol = 17;
11823       else
11824         {
11825           errmsg ("unknown input `%U'", format_unformat_error, i);
11826           return -99;
11827         }
11828     }
11829
11830   if (is_add == -1)
11831     {
11832       errmsg ("expecting: add|del");
11833       return -99;
11834     }
11835   if (classify_table_index == ~0)
11836     {
11837       errmsg ("classifier table not specified");
11838       return -99;
11839     }
11840   if (ip_version == 0)
11841     {
11842       errmsg ("IP version not specified");
11843       return -99;
11844     }
11845
11846   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11847
11848   mp->is_add = is_add;
11849   mp->table_id = htonl (classify_table_index);
11850   mp->ip_version = ip_version;
11851   mp->transport_protocol = transport_protocol;
11852
11853   S (mp);
11854   W (ret);
11855   return ret;
11856 }
11857
11858 static int
11859 api_get_node_index (vat_main_t * vam)
11860 {
11861   unformat_input_t *i = vam->input;
11862   vl_api_get_node_index_t *mp;
11863   u8 *name = 0;
11864   int ret;
11865
11866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11867     {
11868       if (unformat (i, "node %s", &name))
11869         ;
11870       else
11871         break;
11872     }
11873   if (name == 0)
11874     {
11875       errmsg ("node name required");
11876       return -99;
11877     }
11878   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11879     {
11880       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11881       return -99;
11882     }
11883
11884   M (GET_NODE_INDEX, mp);
11885   clib_memcpy (mp->node_name, name, vec_len (name));
11886   vec_free (name);
11887
11888   S (mp);
11889   W (ret);
11890   return ret;
11891 }
11892
11893 static int
11894 api_get_next_index (vat_main_t * vam)
11895 {
11896   unformat_input_t *i = vam->input;
11897   vl_api_get_next_index_t *mp;
11898   u8 *node_name = 0, *next_node_name = 0;
11899   int ret;
11900
11901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11902     {
11903       if (unformat (i, "node-name %s", &node_name))
11904         ;
11905       else if (unformat (i, "next-node-name %s", &next_node_name))
11906         break;
11907     }
11908
11909   if (node_name == 0)
11910     {
11911       errmsg ("node name required");
11912       return -99;
11913     }
11914   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11915     {
11916       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11917       return -99;
11918     }
11919
11920   if (next_node_name == 0)
11921     {
11922       errmsg ("next node name required");
11923       return -99;
11924     }
11925   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11926     {
11927       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11928       return -99;
11929     }
11930
11931   M (GET_NEXT_INDEX, mp);
11932   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11933   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11934   vec_free (node_name);
11935   vec_free (next_node_name);
11936
11937   S (mp);
11938   W (ret);
11939   return ret;
11940 }
11941
11942 static int
11943 api_add_node_next (vat_main_t * vam)
11944 {
11945   unformat_input_t *i = vam->input;
11946   vl_api_add_node_next_t *mp;
11947   u8 *name = 0;
11948   u8 *next = 0;
11949   int ret;
11950
11951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (i, "node %s", &name))
11954         ;
11955       else if (unformat (i, "next %s", &next))
11956         ;
11957       else
11958         break;
11959     }
11960   if (name == 0)
11961     {
11962       errmsg ("node name required");
11963       return -99;
11964     }
11965   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11966     {
11967       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11968       return -99;
11969     }
11970   if (next == 0)
11971     {
11972       errmsg ("next node required");
11973       return -99;
11974     }
11975   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11976     {
11977       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11978       return -99;
11979     }
11980
11981   M (ADD_NODE_NEXT, mp);
11982   clib_memcpy (mp->node_name, name, vec_len (name));
11983   clib_memcpy (mp->next_name, next, vec_len (next));
11984   vec_free (name);
11985   vec_free (next);
11986
11987   S (mp);
11988   W (ret);
11989   return ret;
11990 }
11991
11992 static int
11993 api_l2tpv3_create_tunnel (vat_main_t * vam)
11994 {
11995   unformat_input_t *i = vam->input;
11996   ip6_address_t client_address, our_address;
11997   int client_address_set = 0;
11998   int our_address_set = 0;
11999   u32 local_session_id = 0;
12000   u32 remote_session_id = 0;
12001   u64 local_cookie = 0;
12002   u64 remote_cookie = 0;
12003   u8 l2_sublayer_present = 0;
12004   vl_api_l2tpv3_create_tunnel_t *mp;
12005   int ret;
12006
12007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12008     {
12009       if (unformat (i, "client_address %U", unformat_ip6_address,
12010                     &client_address))
12011         client_address_set = 1;
12012       else if (unformat (i, "our_address %U", unformat_ip6_address,
12013                          &our_address))
12014         our_address_set = 1;
12015       else if (unformat (i, "local_session_id %d", &local_session_id))
12016         ;
12017       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12018         ;
12019       else if (unformat (i, "local_cookie %lld", &local_cookie))
12020         ;
12021       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12022         ;
12023       else if (unformat (i, "l2-sublayer-present"))
12024         l2_sublayer_present = 1;
12025       else
12026         break;
12027     }
12028
12029   if (client_address_set == 0)
12030     {
12031       errmsg ("client_address required");
12032       return -99;
12033     }
12034
12035   if (our_address_set == 0)
12036     {
12037       errmsg ("our_address required");
12038       return -99;
12039     }
12040
12041   M (L2TPV3_CREATE_TUNNEL, mp);
12042
12043   clib_memcpy (mp->client_address, client_address.as_u8,
12044                sizeof (mp->client_address));
12045
12046   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12047
12048   mp->local_session_id = ntohl (local_session_id);
12049   mp->remote_session_id = ntohl (remote_session_id);
12050   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12051   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12052   mp->l2_sublayer_present = l2_sublayer_present;
12053   mp->is_ipv6 = 1;
12054
12055   S (mp);
12056   W (ret);
12057   return ret;
12058 }
12059
12060 static int
12061 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12062 {
12063   unformat_input_t *i = vam->input;
12064   u32 sw_if_index;
12065   u8 sw_if_index_set = 0;
12066   u64 new_local_cookie = 0;
12067   u64 new_remote_cookie = 0;
12068   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12069   int ret;
12070
12071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12072     {
12073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12074         sw_if_index_set = 1;
12075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12076         sw_if_index_set = 1;
12077       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12078         ;
12079       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12080         ;
12081       else
12082         break;
12083     }
12084
12085   if (sw_if_index_set == 0)
12086     {
12087       errmsg ("missing interface name or sw_if_index");
12088       return -99;
12089     }
12090
12091   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12092
12093   mp->sw_if_index = ntohl (sw_if_index);
12094   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12095   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12096
12097   S (mp);
12098   W (ret);
12099   return ret;
12100 }
12101
12102 static int
12103 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12104 {
12105   unformat_input_t *i = vam->input;
12106   vl_api_l2tpv3_interface_enable_disable_t *mp;
12107   u32 sw_if_index;
12108   u8 sw_if_index_set = 0;
12109   u8 enable_disable = 1;
12110   int ret;
12111
12112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12115         sw_if_index_set = 1;
12116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12117         sw_if_index_set = 1;
12118       else if (unformat (i, "enable"))
12119         enable_disable = 1;
12120       else if (unformat (i, "disable"))
12121         enable_disable = 0;
12122       else
12123         break;
12124     }
12125
12126   if (sw_if_index_set == 0)
12127     {
12128       errmsg ("missing interface name or sw_if_index");
12129       return -99;
12130     }
12131
12132   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12133
12134   mp->sw_if_index = ntohl (sw_if_index);
12135   mp->enable_disable = enable_disable;
12136
12137   S (mp);
12138   W (ret);
12139   return ret;
12140 }
12141
12142 static int
12143 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12144 {
12145   unformat_input_t *i = vam->input;
12146   vl_api_l2tpv3_set_lookup_key_t *mp;
12147   u8 key = ~0;
12148   int ret;
12149
12150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12151     {
12152       if (unformat (i, "lookup_v6_src"))
12153         key = L2T_LOOKUP_SRC_ADDRESS;
12154       else if (unformat (i, "lookup_v6_dst"))
12155         key = L2T_LOOKUP_DST_ADDRESS;
12156       else if (unformat (i, "lookup_session_id"))
12157         key = L2T_LOOKUP_SESSION_ID;
12158       else
12159         break;
12160     }
12161
12162   if (key == (u8) ~ 0)
12163     {
12164       errmsg ("l2tp session lookup key unset");
12165       return -99;
12166     }
12167
12168   M (L2TPV3_SET_LOOKUP_KEY, mp);
12169
12170   mp->key = key;
12171
12172   S (mp);
12173   W (ret);
12174   return ret;
12175 }
12176
12177 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12178   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12179 {
12180   vat_main_t *vam = &vat_main;
12181
12182   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12183          format_ip6_address, mp->our_address,
12184          format_ip6_address, mp->client_address,
12185          clib_net_to_host_u32 (mp->sw_if_index));
12186
12187   print (vam->ofp,
12188          "   local cookies %016llx %016llx remote cookie %016llx",
12189          clib_net_to_host_u64 (mp->local_cookie[0]),
12190          clib_net_to_host_u64 (mp->local_cookie[1]),
12191          clib_net_to_host_u64 (mp->remote_cookie));
12192
12193   print (vam->ofp, "   local session-id %d remote session-id %d",
12194          clib_net_to_host_u32 (mp->local_session_id),
12195          clib_net_to_host_u32 (mp->remote_session_id));
12196
12197   print (vam->ofp, "   l2 specific sublayer %s\n",
12198          mp->l2_sublayer_present ? "preset" : "absent");
12199
12200 }
12201
12202 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12203   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12204 {
12205   vat_main_t *vam = &vat_main;
12206   vat_json_node_t *node = NULL;
12207   struct in6_addr addr;
12208
12209   if (VAT_JSON_ARRAY != vam->json_tree.type)
12210     {
12211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12212       vat_json_init_array (&vam->json_tree);
12213     }
12214   node = vat_json_array_add (&vam->json_tree);
12215
12216   vat_json_init_object (node);
12217
12218   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12219   vat_json_object_add_ip6 (node, "our_address", addr);
12220   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12221   vat_json_object_add_ip6 (node, "client_address", addr);
12222
12223   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12224   vat_json_init_array (lc);
12225   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12226   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12227   vat_json_object_add_uint (node, "remote_cookie",
12228                             clib_net_to_host_u64 (mp->remote_cookie));
12229
12230   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12231   vat_json_object_add_uint (node, "local_session_id",
12232                             clib_net_to_host_u32 (mp->local_session_id));
12233   vat_json_object_add_uint (node, "remote_session_id",
12234                             clib_net_to_host_u32 (mp->remote_session_id));
12235   vat_json_object_add_string_copy (node, "l2_sublayer",
12236                                    mp->l2_sublayer_present ? (u8 *) "present"
12237                                    : (u8 *) "absent");
12238 }
12239
12240 static int
12241 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12242 {
12243   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12244   vl_api_control_ping_t *mp_ping;
12245   int ret;
12246
12247   /* Get list of l2tpv3-tunnel interfaces */
12248   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12249   S (mp);
12250
12251   /* Use a control ping for synchronization */
12252   MPING (CONTROL_PING, mp_ping);
12253   S (mp_ping);
12254
12255   W (ret);
12256   return ret;
12257 }
12258
12259
12260 static void vl_api_sw_interface_tap_v2_details_t_handler
12261   (vl_api_sw_interface_tap_v2_details_t * mp)
12262 {
12263   vat_main_t *vam = &vat_main;
12264
12265   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12266                     mp->host_ip4_prefix_len);
12267   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12268                     mp->host_ip6_prefix_len);
12269
12270   print (vam->ofp,
12271          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12272          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12273          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12274          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12275          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12276
12277   vec_free (ip4);
12278   vec_free (ip6);
12279 }
12280
12281 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12282   (vl_api_sw_interface_tap_v2_details_t * mp)
12283 {
12284   vat_main_t *vam = &vat_main;
12285   vat_json_node_t *node = NULL;
12286
12287   if (VAT_JSON_ARRAY != vam->json_tree.type)
12288     {
12289       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12290       vat_json_init_array (&vam->json_tree);
12291     }
12292   node = vat_json_array_add (&vam->json_tree);
12293
12294   vat_json_init_object (node);
12295   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12296   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12297   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12298   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12299   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12300   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12301   vat_json_object_add_string_copy (node, "host_mac_addr",
12302                                    format (0, "%U", format_ethernet_address,
12303                                            &mp->host_mac_addr));
12304   vat_json_object_add_string_copy (node, "host_namespace",
12305                                    mp->host_namespace);
12306   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12307   vat_json_object_add_string_copy (node, "host_ip4_addr",
12308                                    format (0, "%U/%d", format_ip4_address,
12309                                            mp->host_ip4_addr,
12310                                            mp->host_ip4_prefix_len));
12311   vat_json_object_add_string_copy (node, "host_ip6_addr",
12312                                    format (0, "%U/%d", format_ip6_address,
12313                                            mp->host_ip6_addr,
12314                                            mp->host_ip6_prefix_len));
12315
12316 }
12317
12318 static int
12319 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12320 {
12321   vl_api_sw_interface_tap_v2_dump_t *mp;
12322   vl_api_control_ping_t *mp_ping;
12323   int ret;
12324
12325   print (vam->ofp,
12326          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12327          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12328          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12329          "host_ip6_addr");
12330
12331   /* Get list of tap interfaces */
12332   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12333   S (mp);
12334
12335   /* Use a control ping for synchronization */
12336   MPING (CONTROL_PING, mp_ping);
12337   S (mp_ping);
12338
12339   W (ret);
12340   return ret;
12341 }
12342
12343 static void vl_api_sw_interface_virtio_pci_details_t_handler
12344   (vl_api_sw_interface_virtio_pci_details_t * mp)
12345 {
12346   vat_main_t *vam = &vat_main;
12347
12348   typedef union
12349   {
12350     struct
12351     {
12352       u16 domain;
12353       u8 bus;
12354       u8 slot:5;
12355       u8 function:3;
12356     };
12357     u32 as_u32;
12358   } pci_addr_t;
12359   pci_addr_t addr;
12360   addr.as_u32 = ntohl (mp->pci_addr);
12361   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12362                          addr.slot, addr.function);
12363
12364   print (vam->ofp,
12365          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12366          pci_addr, ntohl (mp->sw_if_index),
12367          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12368          format_ethernet_address, mp->mac_addr,
12369          clib_net_to_host_u64 (mp->features));
12370   vec_free (pci_addr);
12371 }
12372
12373 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12374   (vl_api_sw_interface_virtio_pci_details_t * mp)
12375 {
12376   vat_main_t *vam = &vat_main;
12377   vat_json_node_t *node = NULL;
12378
12379   if (VAT_JSON_ARRAY != vam->json_tree.type)
12380     {
12381       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12382       vat_json_init_array (&vam->json_tree);
12383     }
12384   node = vat_json_array_add (&vam->json_tree);
12385
12386   vat_json_init_object (node);
12387   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12388   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12389   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12390   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12391   vat_json_object_add_uint (node, "features",
12392                             clib_net_to_host_u64 (mp->features));
12393   vat_json_object_add_string_copy (node, "mac_addr",
12394                                    format (0, "%U", format_ethernet_address,
12395                                            &mp->mac_addr));
12396 }
12397
12398 static int
12399 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12400 {
12401   vl_api_sw_interface_virtio_pci_dump_t *mp;
12402   vl_api_control_ping_t *mp_ping;
12403   int ret;
12404
12405   print (vam->ofp,
12406          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12407          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12408          "mac_addr", "features");
12409
12410   /* Get list of tap interfaces */
12411   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12412   S (mp);
12413
12414   /* Use a control ping for synchronization */
12415   MPING (CONTROL_PING, mp_ping);
12416   S (mp_ping);
12417
12418   W (ret);
12419   return ret;
12420 }
12421
12422 static int
12423 api_vxlan_offload_rx (vat_main_t * vam)
12424 {
12425   unformat_input_t *line_input = vam->input;
12426   vl_api_vxlan_offload_rx_t *mp;
12427   u32 hw_if_index = ~0, rx_if_index = ~0;
12428   u8 is_add = 1;
12429   int ret;
12430
12431   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12432     {
12433       if (unformat (line_input, "del"))
12434         is_add = 0;
12435       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12436                          &hw_if_index))
12437         ;
12438       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12439         ;
12440       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12441                          &rx_if_index))
12442         ;
12443       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12444         ;
12445       else
12446         {
12447           errmsg ("parse error '%U'", format_unformat_error, line_input);
12448           return -99;
12449         }
12450     }
12451
12452   if (hw_if_index == ~0)
12453     {
12454       errmsg ("no hw interface");
12455       return -99;
12456     }
12457
12458   if (rx_if_index == ~0)
12459     {
12460       errmsg ("no rx tunnel");
12461       return -99;
12462     }
12463
12464   M (VXLAN_OFFLOAD_RX, mp);
12465
12466   mp->hw_if_index = ntohl (hw_if_index);
12467   mp->sw_if_index = ntohl (rx_if_index);
12468   mp->enable = is_add;
12469
12470   S (mp);
12471   W (ret);
12472   return ret;
12473 }
12474
12475 static uword unformat_vxlan_decap_next
12476   (unformat_input_t * input, va_list * args)
12477 {
12478   u32 *result = va_arg (*args, u32 *);
12479   u32 tmp;
12480
12481   if (unformat (input, "l2"))
12482     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12483   else if (unformat (input, "%d", &tmp))
12484     *result = tmp;
12485   else
12486     return 0;
12487   return 1;
12488 }
12489
12490 static int
12491 api_vxlan_add_del_tunnel (vat_main_t * vam)
12492 {
12493   unformat_input_t *line_input = vam->input;
12494   vl_api_vxlan_add_del_tunnel_t *mp;
12495   ip46_address_t src, dst;
12496   u8 is_add = 1;
12497   u8 ipv4_set = 0, ipv6_set = 0;
12498   u8 src_set = 0;
12499   u8 dst_set = 0;
12500   u8 grp_set = 0;
12501   u32 instance = ~0;
12502   u32 mcast_sw_if_index = ~0;
12503   u32 encap_vrf_id = 0;
12504   u32 decap_next_index = ~0;
12505   u32 vni = 0;
12506   int ret;
12507
12508   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12509   clib_memset (&src, 0, sizeof src);
12510   clib_memset (&dst, 0, sizeof dst);
12511
12512   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12513     {
12514       if (unformat (line_input, "del"))
12515         is_add = 0;
12516       else if (unformat (line_input, "instance %d", &instance))
12517         ;
12518       else
12519         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12520         {
12521           ipv4_set = 1;
12522           src_set = 1;
12523         }
12524       else
12525         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12526         {
12527           ipv4_set = 1;
12528           dst_set = 1;
12529         }
12530       else
12531         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12532         {
12533           ipv6_set = 1;
12534           src_set = 1;
12535         }
12536       else
12537         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12538         {
12539           ipv6_set = 1;
12540           dst_set = 1;
12541         }
12542       else if (unformat (line_input, "group %U %U",
12543                          unformat_ip4_address, &dst.ip4,
12544                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12545         {
12546           grp_set = dst_set = 1;
12547           ipv4_set = 1;
12548         }
12549       else if (unformat (line_input, "group %U",
12550                          unformat_ip4_address, &dst.ip4))
12551         {
12552           grp_set = dst_set = 1;
12553           ipv4_set = 1;
12554         }
12555       else if (unformat (line_input, "group %U %U",
12556                          unformat_ip6_address, &dst.ip6,
12557                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12558         {
12559           grp_set = dst_set = 1;
12560           ipv6_set = 1;
12561         }
12562       else if (unformat (line_input, "group %U",
12563                          unformat_ip6_address, &dst.ip6))
12564         {
12565           grp_set = dst_set = 1;
12566           ipv6_set = 1;
12567         }
12568       else
12569         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12570         ;
12571       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12572         ;
12573       else if (unformat (line_input, "decap-next %U",
12574                          unformat_vxlan_decap_next, &decap_next_index))
12575         ;
12576       else if (unformat (line_input, "vni %d", &vni))
12577         ;
12578       else
12579         {
12580           errmsg ("parse error '%U'", format_unformat_error, line_input);
12581           return -99;
12582         }
12583     }
12584
12585   if (src_set == 0)
12586     {
12587       errmsg ("tunnel src address not specified");
12588       return -99;
12589     }
12590   if (dst_set == 0)
12591     {
12592       errmsg ("tunnel dst address not specified");
12593       return -99;
12594     }
12595
12596   if (grp_set && !ip46_address_is_multicast (&dst))
12597     {
12598       errmsg ("tunnel group address not multicast");
12599       return -99;
12600     }
12601   if (grp_set && mcast_sw_if_index == ~0)
12602     {
12603       errmsg ("tunnel nonexistent multicast device");
12604       return -99;
12605     }
12606   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12607     {
12608       errmsg ("tunnel dst address must be unicast");
12609       return -99;
12610     }
12611
12612
12613   if (ipv4_set && ipv6_set)
12614     {
12615       errmsg ("both IPv4 and IPv6 addresses specified");
12616       return -99;
12617     }
12618
12619   if ((vni == 0) || (vni >> 24))
12620     {
12621       errmsg ("vni not specified or out of range");
12622       return -99;
12623     }
12624
12625   M (VXLAN_ADD_DEL_TUNNEL, mp);
12626
12627   if (ipv6_set)
12628     {
12629       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12630       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12631     }
12632   else
12633     {
12634       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12635       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12636     }
12637
12638   mp->instance = htonl (instance);
12639   mp->encap_vrf_id = ntohl (encap_vrf_id);
12640   mp->decap_next_index = ntohl (decap_next_index);
12641   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12642   mp->vni = ntohl (vni);
12643   mp->is_add = is_add;
12644   mp->is_ipv6 = ipv6_set;
12645
12646   S (mp);
12647   W (ret);
12648   return ret;
12649 }
12650
12651 static void vl_api_vxlan_tunnel_details_t_handler
12652   (vl_api_vxlan_tunnel_details_t * mp)
12653 {
12654   vat_main_t *vam = &vat_main;
12655   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12656   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12657
12658   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12659          ntohl (mp->sw_if_index),
12660          ntohl (mp->instance),
12661          format_ip46_address, &src, IP46_TYPE_ANY,
12662          format_ip46_address, &dst, IP46_TYPE_ANY,
12663          ntohl (mp->encap_vrf_id),
12664          ntohl (mp->decap_next_index), ntohl (mp->vni),
12665          ntohl (mp->mcast_sw_if_index));
12666 }
12667
12668 static void vl_api_vxlan_tunnel_details_t_handler_json
12669   (vl_api_vxlan_tunnel_details_t * mp)
12670 {
12671   vat_main_t *vam = &vat_main;
12672   vat_json_node_t *node = NULL;
12673
12674   if (VAT_JSON_ARRAY != vam->json_tree.type)
12675     {
12676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12677       vat_json_init_array (&vam->json_tree);
12678     }
12679   node = vat_json_array_add (&vam->json_tree);
12680
12681   vat_json_init_object (node);
12682   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12683
12684   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12685
12686   if (mp->is_ipv6)
12687     {
12688       struct in6_addr ip6;
12689
12690       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12691       vat_json_object_add_ip6 (node, "src_address", ip6);
12692       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12693       vat_json_object_add_ip6 (node, "dst_address", ip6);
12694     }
12695   else
12696     {
12697       struct in_addr ip4;
12698
12699       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12700       vat_json_object_add_ip4 (node, "src_address", ip4);
12701       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12702       vat_json_object_add_ip4 (node, "dst_address", ip4);
12703     }
12704   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12705   vat_json_object_add_uint (node, "decap_next_index",
12706                             ntohl (mp->decap_next_index));
12707   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12708   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12709   vat_json_object_add_uint (node, "mcast_sw_if_index",
12710                             ntohl (mp->mcast_sw_if_index));
12711 }
12712
12713 static int
12714 api_vxlan_tunnel_dump (vat_main_t * vam)
12715 {
12716   unformat_input_t *i = vam->input;
12717   vl_api_vxlan_tunnel_dump_t *mp;
12718   vl_api_control_ping_t *mp_ping;
12719   u32 sw_if_index;
12720   u8 sw_if_index_set = 0;
12721   int ret;
12722
12723   /* Parse args required to build the message */
12724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12725     {
12726       if (unformat (i, "sw_if_index %d", &sw_if_index))
12727         sw_if_index_set = 1;
12728       else
12729         break;
12730     }
12731
12732   if (sw_if_index_set == 0)
12733     {
12734       sw_if_index = ~0;
12735     }
12736
12737   if (!vam->json_output)
12738     {
12739       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12740              "sw_if_index", "instance", "src_address", "dst_address",
12741              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12742     }
12743
12744   /* Get list of vxlan-tunnel interfaces */
12745   M (VXLAN_TUNNEL_DUMP, mp);
12746
12747   mp->sw_if_index = htonl (sw_if_index);
12748
12749   S (mp);
12750
12751   /* Use a control ping for synchronization */
12752   MPING (CONTROL_PING, mp_ping);
12753   S (mp_ping);
12754
12755   W (ret);
12756   return ret;
12757 }
12758
12759 static uword unformat_geneve_decap_next
12760   (unformat_input_t * input, va_list * args)
12761 {
12762   u32 *result = va_arg (*args, u32 *);
12763   u32 tmp;
12764
12765   if (unformat (input, "l2"))
12766     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12767   else if (unformat (input, "%d", &tmp))
12768     *result = tmp;
12769   else
12770     return 0;
12771   return 1;
12772 }
12773
12774 static int
12775 api_geneve_add_del_tunnel (vat_main_t * vam)
12776 {
12777   unformat_input_t *line_input = vam->input;
12778   vl_api_geneve_add_del_tunnel_t *mp;
12779   ip46_address_t src, dst;
12780   u8 is_add = 1;
12781   u8 ipv4_set = 0, ipv6_set = 0;
12782   u8 src_set = 0;
12783   u8 dst_set = 0;
12784   u8 grp_set = 0;
12785   u32 mcast_sw_if_index = ~0;
12786   u32 encap_vrf_id = 0;
12787   u32 decap_next_index = ~0;
12788   u32 vni = 0;
12789   int ret;
12790
12791   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12792   clib_memset (&src, 0, sizeof src);
12793   clib_memset (&dst, 0, sizeof dst);
12794
12795   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12796     {
12797       if (unformat (line_input, "del"))
12798         is_add = 0;
12799       else
12800         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12801         {
12802           ipv4_set = 1;
12803           src_set = 1;
12804         }
12805       else
12806         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12807         {
12808           ipv4_set = 1;
12809           dst_set = 1;
12810         }
12811       else
12812         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12813         {
12814           ipv6_set = 1;
12815           src_set = 1;
12816         }
12817       else
12818         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12819         {
12820           ipv6_set = 1;
12821           dst_set = 1;
12822         }
12823       else if (unformat (line_input, "group %U %U",
12824                          unformat_ip4_address, &dst.ip4,
12825                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12826         {
12827           grp_set = dst_set = 1;
12828           ipv4_set = 1;
12829         }
12830       else if (unformat (line_input, "group %U",
12831                          unformat_ip4_address, &dst.ip4))
12832         {
12833           grp_set = dst_set = 1;
12834           ipv4_set = 1;
12835         }
12836       else if (unformat (line_input, "group %U %U",
12837                          unformat_ip6_address, &dst.ip6,
12838                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12839         {
12840           grp_set = dst_set = 1;
12841           ipv6_set = 1;
12842         }
12843       else if (unformat (line_input, "group %U",
12844                          unformat_ip6_address, &dst.ip6))
12845         {
12846           grp_set = dst_set = 1;
12847           ipv6_set = 1;
12848         }
12849       else
12850         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12851         ;
12852       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12853         ;
12854       else if (unformat (line_input, "decap-next %U",
12855                          unformat_geneve_decap_next, &decap_next_index))
12856         ;
12857       else if (unformat (line_input, "vni %d", &vni))
12858         ;
12859       else
12860         {
12861           errmsg ("parse error '%U'", format_unformat_error, line_input);
12862           return -99;
12863         }
12864     }
12865
12866   if (src_set == 0)
12867     {
12868       errmsg ("tunnel src address not specified");
12869       return -99;
12870     }
12871   if (dst_set == 0)
12872     {
12873       errmsg ("tunnel dst address not specified");
12874       return -99;
12875     }
12876
12877   if (grp_set && !ip46_address_is_multicast (&dst))
12878     {
12879       errmsg ("tunnel group address not multicast");
12880       return -99;
12881     }
12882   if (grp_set && mcast_sw_if_index == ~0)
12883     {
12884       errmsg ("tunnel nonexistent multicast device");
12885       return -99;
12886     }
12887   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12888     {
12889       errmsg ("tunnel dst address must be unicast");
12890       return -99;
12891     }
12892
12893
12894   if (ipv4_set && ipv6_set)
12895     {
12896       errmsg ("both IPv4 and IPv6 addresses specified");
12897       return -99;
12898     }
12899
12900   if ((vni == 0) || (vni >> 24))
12901     {
12902       errmsg ("vni not specified or out of range");
12903       return -99;
12904     }
12905
12906   M (GENEVE_ADD_DEL_TUNNEL, mp);
12907
12908   if (ipv6_set)
12909     {
12910       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12911       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12912     }
12913   else
12914     {
12915       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12916       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12917     }
12918   mp->encap_vrf_id = ntohl (encap_vrf_id);
12919   mp->decap_next_index = ntohl (decap_next_index);
12920   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12921   mp->vni = ntohl (vni);
12922   mp->is_add = is_add;
12923   mp->is_ipv6 = ipv6_set;
12924
12925   S (mp);
12926   W (ret);
12927   return ret;
12928 }
12929
12930 static void vl_api_geneve_tunnel_details_t_handler
12931   (vl_api_geneve_tunnel_details_t * mp)
12932 {
12933   vat_main_t *vam = &vat_main;
12934   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12935   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12936
12937   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12938          ntohl (mp->sw_if_index),
12939          format_ip46_address, &src, IP46_TYPE_ANY,
12940          format_ip46_address, &dst, IP46_TYPE_ANY,
12941          ntohl (mp->encap_vrf_id),
12942          ntohl (mp->decap_next_index), ntohl (mp->vni),
12943          ntohl (mp->mcast_sw_if_index));
12944 }
12945
12946 static void vl_api_geneve_tunnel_details_t_handler_json
12947   (vl_api_geneve_tunnel_details_t * mp)
12948 {
12949   vat_main_t *vam = &vat_main;
12950   vat_json_node_t *node = NULL;
12951
12952   if (VAT_JSON_ARRAY != vam->json_tree.type)
12953     {
12954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12955       vat_json_init_array (&vam->json_tree);
12956     }
12957   node = vat_json_array_add (&vam->json_tree);
12958
12959   vat_json_init_object (node);
12960   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12961   if (mp->is_ipv6)
12962     {
12963       struct in6_addr ip6;
12964
12965       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12966       vat_json_object_add_ip6 (node, "src_address", ip6);
12967       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12968       vat_json_object_add_ip6 (node, "dst_address", ip6);
12969     }
12970   else
12971     {
12972       struct in_addr ip4;
12973
12974       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12975       vat_json_object_add_ip4 (node, "src_address", ip4);
12976       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12977       vat_json_object_add_ip4 (node, "dst_address", ip4);
12978     }
12979   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12980   vat_json_object_add_uint (node, "decap_next_index",
12981                             ntohl (mp->decap_next_index));
12982   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12983   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12984   vat_json_object_add_uint (node, "mcast_sw_if_index",
12985                             ntohl (mp->mcast_sw_if_index));
12986 }
12987
12988 static int
12989 api_geneve_tunnel_dump (vat_main_t * vam)
12990 {
12991   unformat_input_t *i = vam->input;
12992   vl_api_geneve_tunnel_dump_t *mp;
12993   vl_api_control_ping_t *mp_ping;
12994   u32 sw_if_index;
12995   u8 sw_if_index_set = 0;
12996   int ret;
12997
12998   /* Parse args required to build the message */
12999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13000     {
13001       if (unformat (i, "sw_if_index %d", &sw_if_index))
13002         sw_if_index_set = 1;
13003       else
13004         break;
13005     }
13006
13007   if (sw_if_index_set == 0)
13008     {
13009       sw_if_index = ~0;
13010     }
13011
13012   if (!vam->json_output)
13013     {
13014       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13015              "sw_if_index", "local_address", "remote_address",
13016              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13017     }
13018
13019   /* Get list of geneve-tunnel interfaces */
13020   M (GENEVE_TUNNEL_DUMP, mp);
13021
13022   mp->sw_if_index = htonl (sw_if_index);
13023
13024   S (mp);
13025
13026   /* Use a control ping for synchronization */
13027   M (CONTROL_PING, mp_ping);
13028   S (mp_ping);
13029
13030   W (ret);
13031   return ret;
13032 }
13033
13034 static int
13035 api_gre_tunnel_add_del (vat_main_t * vam)
13036 {
13037   unformat_input_t *line_input = vam->input;
13038   vl_api_address_t src = { }, dst =
13039   {
13040   };
13041   vl_api_gre_tunnel_add_del_t *mp;
13042   vl_api_gre_tunnel_type_t t_type;
13043   u8 is_add = 1;
13044   u8 src_set = 0;
13045   u8 dst_set = 0;
13046   u32 outer_fib_id = 0;
13047   u32 session_id = 0;
13048   u32 instance = ~0;
13049   int ret;
13050
13051   t_type = GRE_API_TUNNEL_TYPE_L3;
13052
13053   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13054     {
13055       if (unformat (line_input, "del"))
13056         is_add = 0;
13057       else if (unformat (line_input, "instance %d", &instance))
13058         ;
13059       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13060         {
13061           src_set = 1;
13062         }
13063       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13064         {
13065           dst_set = 1;
13066         }
13067       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13068         ;
13069       else if (unformat (line_input, "teb"))
13070         t_type = GRE_API_TUNNEL_TYPE_TEB;
13071       else if (unformat (line_input, "erspan %d", &session_id))
13072         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13073       else
13074         {
13075           errmsg ("parse error '%U'", format_unformat_error, line_input);
13076           return -99;
13077         }
13078     }
13079
13080   if (src_set == 0)
13081     {
13082       errmsg ("tunnel src address not specified");
13083       return -99;
13084     }
13085   if (dst_set == 0)
13086     {
13087       errmsg ("tunnel dst address not specified");
13088       return -99;
13089     }
13090
13091   M (GRE_TUNNEL_ADD_DEL, mp);
13092
13093   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13094   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13095
13096   mp->tunnel.instance = htonl (instance);
13097   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13098   mp->is_add = is_add;
13099   mp->tunnel.session_id = htons ((u16) session_id);
13100   mp->tunnel.type = htonl (t_type);
13101
13102   S (mp);
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static void vl_api_gre_tunnel_details_t_handler
13108   (vl_api_gre_tunnel_details_t * mp)
13109 {
13110   vat_main_t *vam = &vat_main;
13111
13112   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13113          ntohl (mp->tunnel.sw_if_index),
13114          ntohl (mp->tunnel.instance),
13115          format_vl_api_address, &mp->tunnel.src,
13116          format_vl_api_address, &mp->tunnel.dst,
13117          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13118          ntohl (mp->tunnel.session_id));
13119 }
13120
13121 static void vl_api_gre_tunnel_details_t_handler_json
13122   (vl_api_gre_tunnel_details_t * mp)
13123 {
13124   vat_main_t *vam = &vat_main;
13125   vat_json_node_t *node = NULL;
13126
13127   if (VAT_JSON_ARRAY != vam->json_tree.type)
13128     {
13129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13130       vat_json_init_array (&vam->json_tree);
13131     }
13132   node = vat_json_array_add (&vam->json_tree);
13133
13134   vat_json_init_object (node);
13135   vat_json_object_add_uint (node, "sw_if_index",
13136                             ntohl (mp->tunnel.sw_if_index));
13137   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13138
13139   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13140   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13141   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13142   vat_json_object_add_uint (node, "outer_fib_id",
13143                             ntohl (mp->tunnel.outer_fib_id));
13144   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13145 }
13146
13147 static int
13148 api_gre_tunnel_dump (vat_main_t * vam)
13149 {
13150   unformat_input_t *i = vam->input;
13151   vl_api_gre_tunnel_dump_t *mp;
13152   vl_api_control_ping_t *mp_ping;
13153   u32 sw_if_index;
13154   u8 sw_if_index_set = 0;
13155   int ret;
13156
13157   /* Parse args required to build the message */
13158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13159     {
13160       if (unformat (i, "sw_if_index %d", &sw_if_index))
13161         sw_if_index_set = 1;
13162       else
13163         break;
13164     }
13165
13166   if (sw_if_index_set == 0)
13167     {
13168       sw_if_index = ~0;
13169     }
13170
13171   if (!vam->json_output)
13172     {
13173       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13174              "sw_if_index", "instance", "src_address", "dst_address",
13175              "tunnel_type", "outer_fib_id", "session_id");
13176     }
13177
13178   /* Get list of gre-tunnel interfaces */
13179   M (GRE_TUNNEL_DUMP, mp);
13180
13181   mp->sw_if_index = htonl (sw_if_index);
13182
13183   S (mp);
13184
13185   /* Use a control ping for synchronization */
13186   MPING (CONTROL_PING, mp_ping);
13187   S (mp_ping);
13188
13189   W (ret);
13190   return ret;
13191 }
13192
13193 static int
13194 api_l2_fib_clear_table (vat_main_t * vam)
13195 {
13196 //  unformat_input_t * i = vam->input;
13197   vl_api_l2_fib_clear_table_t *mp;
13198   int ret;
13199
13200   M (L2_FIB_CLEAR_TABLE, mp);
13201
13202   S (mp);
13203   W (ret);
13204   return ret;
13205 }
13206
13207 static int
13208 api_l2_interface_efp_filter (vat_main_t * vam)
13209 {
13210   unformat_input_t *i = vam->input;
13211   vl_api_l2_interface_efp_filter_t *mp;
13212   u32 sw_if_index;
13213   u8 enable = 1;
13214   u8 sw_if_index_set = 0;
13215   int ret;
13216
13217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13218     {
13219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13220         sw_if_index_set = 1;
13221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13222         sw_if_index_set = 1;
13223       else if (unformat (i, "enable"))
13224         enable = 1;
13225       else if (unformat (i, "disable"))
13226         enable = 0;
13227       else
13228         {
13229           clib_warning ("parse error '%U'", format_unformat_error, i);
13230           return -99;
13231         }
13232     }
13233
13234   if (sw_if_index_set == 0)
13235     {
13236       errmsg ("missing sw_if_index");
13237       return -99;
13238     }
13239
13240   M (L2_INTERFACE_EFP_FILTER, mp);
13241
13242   mp->sw_if_index = ntohl (sw_if_index);
13243   mp->enable_disable = enable;
13244
13245   S (mp);
13246   W (ret);
13247   return ret;
13248 }
13249
13250 #define foreach_vtr_op                          \
13251 _("disable",  L2_VTR_DISABLED)                  \
13252 _("push-1",  L2_VTR_PUSH_1)                     \
13253 _("push-2",  L2_VTR_PUSH_2)                     \
13254 _("pop-1",  L2_VTR_POP_1)                       \
13255 _("pop-2",  L2_VTR_POP_2)                       \
13256 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13257 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13258 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13259 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13260
13261 static int
13262 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13263 {
13264   unformat_input_t *i = vam->input;
13265   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13266   u32 sw_if_index;
13267   u8 sw_if_index_set = 0;
13268   u8 vtr_op_set = 0;
13269   u32 vtr_op = 0;
13270   u32 push_dot1q = 1;
13271   u32 tag1 = ~0;
13272   u32 tag2 = ~0;
13273   int ret;
13274
13275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13276     {
13277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13278         sw_if_index_set = 1;
13279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13280         sw_if_index_set = 1;
13281       else if (unformat (i, "vtr_op %d", &vtr_op))
13282         vtr_op_set = 1;
13283 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13284       foreach_vtr_op
13285 #undef _
13286         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13287         ;
13288       else if (unformat (i, "tag1 %d", &tag1))
13289         ;
13290       else if (unformat (i, "tag2 %d", &tag2))
13291         ;
13292       else
13293         {
13294           clib_warning ("parse error '%U'", format_unformat_error, i);
13295           return -99;
13296         }
13297     }
13298
13299   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13300     {
13301       errmsg ("missing vtr operation or sw_if_index");
13302       return -99;
13303     }
13304
13305   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13306   mp->sw_if_index = ntohl (sw_if_index);
13307   mp->vtr_op = ntohl (vtr_op);
13308   mp->push_dot1q = ntohl (push_dot1q);
13309   mp->tag1 = ntohl (tag1);
13310   mp->tag2 = ntohl (tag2);
13311
13312   S (mp);
13313   W (ret);
13314   return ret;
13315 }
13316
13317 static int
13318 api_create_vhost_user_if (vat_main_t * vam)
13319 {
13320   unformat_input_t *i = vam->input;
13321   vl_api_create_vhost_user_if_t *mp;
13322   u8 *file_name;
13323   u8 is_server = 0;
13324   u8 file_name_set = 0;
13325   u32 custom_dev_instance = ~0;
13326   u8 hwaddr[6];
13327   u8 use_custom_mac = 0;
13328   u8 disable_mrg_rxbuf = 0;
13329   u8 disable_indirect_desc = 0;
13330   u8 *tag = 0;
13331   int ret;
13332
13333   /* Shut up coverity */
13334   clib_memset (hwaddr, 0, sizeof (hwaddr));
13335
13336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13337     {
13338       if (unformat (i, "socket %s", &file_name))
13339         {
13340           file_name_set = 1;
13341         }
13342       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13343         ;
13344       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13345         use_custom_mac = 1;
13346       else if (unformat (i, "server"))
13347         is_server = 1;
13348       else if (unformat (i, "disable_mrg_rxbuf"))
13349         disable_mrg_rxbuf = 1;
13350       else if (unformat (i, "disable_indirect_desc"))
13351         disable_indirect_desc = 1;
13352       else if (unformat (i, "tag %s", &tag))
13353         ;
13354       else
13355         break;
13356     }
13357
13358   if (file_name_set == 0)
13359     {
13360       errmsg ("missing socket file name");
13361       return -99;
13362     }
13363
13364   if (vec_len (file_name) > 255)
13365     {
13366       errmsg ("socket file name too long");
13367       return -99;
13368     }
13369   vec_add1 (file_name, 0);
13370
13371   M (CREATE_VHOST_USER_IF, mp);
13372
13373   mp->is_server = is_server;
13374   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13375   mp->disable_indirect_desc = disable_indirect_desc;
13376   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13377   vec_free (file_name);
13378   if (custom_dev_instance != ~0)
13379     {
13380       mp->renumber = 1;
13381       mp->custom_dev_instance = ntohl (custom_dev_instance);
13382     }
13383
13384   mp->use_custom_mac = use_custom_mac;
13385   clib_memcpy (mp->mac_address, hwaddr, 6);
13386   if (tag)
13387     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13388   vec_free (tag);
13389
13390   S (mp);
13391   W (ret);
13392   return ret;
13393 }
13394
13395 static int
13396 api_modify_vhost_user_if (vat_main_t * vam)
13397 {
13398   unformat_input_t *i = vam->input;
13399   vl_api_modify_vhost_user_if_t *mp;
13400   u8 *file_name;
13401   u8 is_server = 0;
13402   u8 file_name_set = 0;
13403   u32 custom_dev_instance = ~0;
13404   u8 sw_if_index_set = 0;
13405   u32 sw_if_index = (u32) ~ 0;
13406   int ret;
13407
13408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13409     {
13410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13411         sw_if_index_set = 1;
13412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13413         sw_if_index_set = 1;
13414       else if (unformat (i, "socket %s", &file_name))
13415         {
13416           file_name_set = 1;
13417         }
13418       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13419         ;
13420       else if (unformat (i, "server"))
13421         is_server = 1;
13422       else
13423         break;
13424     }
13425
13426   if (sw_if_index_set == 0)
13427     {
13428       errmsg ("missing sw_if_index or interface name");
13429       return -99;
13430     }
13431
13432   if (file_name_set == 0)
13433     {
13434       errmsg ("missing socket file name");
13435       return -99;
13436     }
13437
13438   if (vec_len (file_name) > 255)
13439     {
13440       errmsg ("socket file name too long");
13441       return -99;
13442     }
13443   vec_add1 (file_name, 0);
13444
13445   M (MODIFY_VHOST_USER_IF, mp);
13446
13447   mp->sw_if_index = ntohl (sw_if_index);
13448   mp->is_server = is_server;
13449   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13450   vec_free (file_name);
13451   if (custom_dev_instance != ~0)
13452     {
13453       mp->renumber = 1;
13454       mp->custom_dev_instance = ntohl (custom_dev_instance);
13455     }
13456
13457   S (mp);
13458   W (ret);
13459   return ret;
13460 }
13461
13462 static int
13463 api_delete_vhost_user_if (vat_main_t * vam)
13464 {
13465   unformat_input_t *i = vam->input;
13466   vl_api_delete_vhost_user_if_t *mp;
13467   u32 sw_if_index = ~0;
13468   u8 sw_if_index_set = 0;
13469   int ret;
13470
13471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13474         sw_if_index_set = 1;
13475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13476         sw_if_index_set = 1;
13477       else
13478         break;
13479     }
13480
13481   if (sw_if_index_set == 0)
13482     {
13483       errmsg ("missing sw_if_index or interface name");
13484       return -99;
13485     }
13486
13487
13488   M (DELETE_VHOST_USER_IF, mp);
13489
13490   mp->sw_if_index = ntohl (sw_if_index);
13491
13492   S (mp);
13493   W (ret);
13494   return ret;
13495 }
13496
13497 static void vl_api_sw_interface_vhost_user_details_t_handler
13498   (vl_api_sw_interface_vhost_user_details_t * mp)
13499 {
13500   vat_main_t *vam = &vat_main;
13501
13502   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13503          (char *) mp->interface_name,
13504          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13505          clib_net_to_host_u64 (mp->features), mp->is_server,
13506          ntohl (mp->num_regions), (char *) mp->sock_filename);
13507   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13508 }
13509
13510 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13511   (vl_api_sw_interface_vhost_user_details_t * mp)
13512 {
13513   vat_main_t *vam = &vat_main;
13514   vat_json_node_t *node = NULL;
13515
13516   if (VAT_JSON_ARRAY != vam->json_tree.type)
13517     {
13518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13519       vat_json_init_array (&vam->json_tree);
13520     }
13521   node = vat_json_array_add (&vam->json_tree);
13522
13523   vat_json_init_object (node);
13524   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13525   vat_json_object_add_string_copy (node, "interface_name",
13526                                    mp->interface_name);
13527   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13528                             ntohl (mp->virtio_net_hdr_sz));
13529   vat_json_object_add_uint (node, "features",
13530                             clib_net_to_host_u64 (mp->features));
13531   vat_json_object_add_uint (node, "is_server", mp->is_server);
13532   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13533   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13534   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13535 }
13536
13537 static int
13538 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13539 {
13540   vl_api_sw_interface_vhost_user_dump_t *mp;
13541   vl_api_control_ping_t *mp_ping;
13542   int ret;
13543   print (vam->ofp,
13544          "Interface name            idx hdr_sz features server regions filename");
13545
13546   /* Get list of vhost-user interfaces */
13547   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13548   S (mp);
13549
13550   /* Use a control ping for synchronization */
13551   MPING (CONTROL_PING, mp_ping);
13552   S (mp_ping);
13553
13554   W (ret);
13555   return ret;
13556 }
13557
13558 static int
13559 api_show_version (vat_main_t * vam)
13560 {
13561   vl_api_show_version_t *mp;
13562   int ret;
13563
13564   M (SHOW_VERSION, mp);
13565
13566   S (mp);
13567   W (ret);
13568   return ret;
13569 }
13570
13571
13572 static int
13573 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13574 {
13575   unformat_input_t *line_input = vam->input;
13576   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13577   ip4_address_t local4, remote4;
13578   ip6_address_t local6, remote6;
13579   u8 is_add = 1;
13580   u8 ipv4_set = 0, ipv6_set = 0;
13581   u8 local_set = 0;
13582   u8 remote_set = 0;
13583   u8 grp_set = 0;
13584   u32 mcast_sw_if_index = ~0;
13585   u32 encap_vrf_id = 0;
13586   u32 decap_vrf_id = 0;
13587   u8 protocol = ~0;
13588   u32 vni;
13589   u8 vni_set = 0;
13590   int ret;
13591
13592   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13593   clib_memset (&local4, 0, sizeof local4);
13594   clib_memset (&remote4, 0, sizeof remote4);
13595   clib_memset (&local6, 0, sizeof local6);
13596   clib_memset (&remote6, 0, sizeof remote6);
13597
13598   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13599     {
13600       if (unformat (line_input, "del"))
13601         is_add = 0;
13602       else if (unformat (line_input, "local %U",
13603                          unformat_ip4_address, &local4))
13604         {
13605           local_set = 1;
13606           ipv4_set = 1;
13607         }
13608       else if (unformat (line_input, "remote %U",
13609                          unformat_ip4_address, &remote4))
13610         {
13611           remote_set = 1;
13612           ipv4_set = 1;
13613         }
13614       else if (unformat (line_input, "local %U",
13615                          unformat_ip6_address, &local6))
13616         {
13617           local_set = 1;
13618           ipv6_set = 1;
13619         }
13620       else if (unformat (line_input, "remote %U",
13621                          unformat_ip6_address, &remote6))
13622         {
13623           remote_set = 1;
13624           ipv6_set = 1;
13625         }
13626       else if (unformat (line_input, "group %U %U",
13627                          unformat_ip4_address, &remote4,
13628                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13629         {
13630           grp_set = remote_set = 1;
13631           ipv4_set = 1;
13632         }
13633       else if (unformat (line_input, "group %U",
13634                          unformat_ip4_address, &remote4))
13635         {
13636           grp_set = remote_set = 1;
13637           ipv4_set = 1;
13638         }
13639       else if (unformat (line_input, "group %U %U",
13640                          unformat_ip6_address, &remote6,
13641                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13642         {
13643           grp_set = remote_set = 1;
13644           ipv6_set = 1;
13645         }
13646       else if (unformat (line_input, "group %U",
13647                          unformat_ip6_address, &remote6))
13648         {
13649           grp_set = remote_set = 1;
13650           ipv6_set = 1;
13651         }
13652       else
13653         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13654         ;
13655       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13656         ;
13657       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13658         ;
13659       else if (unformat (line_input, "vni %d", &vni))
13660         vni_set = 1;
13661       else if (unformat (line_input, "next-ip4"))
13662         protocol = 1;
13663       else if (unformat (line_input, "next-ip6"))
13664         protocol = 2;
13665       else if (unformat (line_input, "next-ethernet"))
13666         protocol = 3;
13667       else if (unformat (line_input, "next-nsh"))
13668         protocol = 4;
13669       else
13670         {
13671           errmsg ("parse error '%U'", format_unformat_error, line_input);
13672           return -99;
13673         }
13674     }
13675
13676   if (local_set == 0)
13677     {
13678       errmsg ("tunnel local address not specified");
13679       return -99;
13680     }
13681   if (remote_set == 0)
13682     {
13683       errmsg ("tunnel remote address not specified");
13684       return -99;
13685     }
13686   if (grp_set && mcast_sw_if_index == ~0)
13687     {
13688       errmsg ("tunnel nonexistent multicast device");
13689       return -99;
13690     }
13691   if (ipv4_set && ipv6_set)
13692     {
13693       errmsg ("both IPv4 and IPv6 addresses specified");
13694       return -99;
13695     }
13696
13697   if (vni_set == 0)
13698     {
13699       errmsg ("vni not specified");
13700       return -99;
13701     }
13702
13703   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13704
13705
13706   if (ipv6_set)
13707     {
13708       clib_memcpy (&mp->local, &local6, sizeof (local6));
13709       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13710     }
13711   else
13712     {
13713       clib_memcpy (&mp->local, &local4, sizeof (local4));
13714       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13715     }
13716
13717   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13718   mp->encap_vrf_id = ntohl (encap_vrf_id);
13719   mp->decap_vrf_id = ntohl (decap_vrf_id);
13720   mp->protocol = protocol;
13721   mp->vni = ntohl (vni);
13722   mp->is_add = is_add;
13723   mp->is_ipv6 = ipv6_set;
13724
13725   S (mp);
13726   W (ret);
13727   return ret;
13728 }
13729
13730 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13731   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13732 {
13733   vat_main_t *vam = &vat_main;
13734   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13735   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13736
13737   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13738          ntohl (mp->sw_if_index),
13739          format_ip46_address, &local, IP46_TYPE_ANY,
13740          format_ip46_address, &remote, IP46_TYPE_ANY,
13741          ntohl (mp->vni), mp->protocol,
13742          ntohl (mp->mcast_sw_if_index),
13743          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13744 }
13745
13746
13747 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13748   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13749 {
13750   vat_main_t *vam = &vat_main;
13751   vat_json_node_t *node = NULL;
13752   struct in_addr ip4;
13753   struct in6_addr ip6;
13754
13755   if (VAT_JSON_ARRAY != vam->json_tree.type)
13756     {
13757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13758       vat_json_init_array (&vam->json_tree);
13759     }
13760   node = vat_json_array_add (&vam->json_tree);
13761
13762   vat_json_init_object (node);
13763   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13764   if (mp->is_ipv6)
13765     {
13766       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13767       vat_json_object_add_ip6 (node, "local", ip6);
13768       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13769       vat_json_object_add_ip6 (node, "remote", ip6);
13770     }
13771   else
13772     {
13773       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13774       vat_json_object_add_ip4 (node, "local", ip4);
13775       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13776       vat_json_object_add_ip4 (node, "remote", ip4);
13777     }
13778   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13779   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13780   vat_json_object_add_uint (node, "mcast_sw_if_index",
13781                             ntohl (mp->mcast_sw_if_index));
13782   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13783   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13784   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13785 }
13786
13787 static int
13788 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13789 {
13790   unformat_input_t *i = vam->input;
13791   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13792   vl_api_control_ping_t *mp_ping;
13793   u32 sw_if_index;
13794   u8 sw_if_index_set = 0;
13795   int ret;
13796
13797   /* Parse args required to build the message */
13798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13799     {
13800       if (unformat (i, "sw_if_index %d", &sw_if_index))
13801         sw_if_index_set = 1;
13802       else
13803         break;
13804     }
13805
13806   if (sw_if_index_set == 0)
13807     {
13808       sw_if_index = ~0;
13809     }
13810
13811   if (!vam->json_output)
13812     {
13813       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13814              "sw_if_index", "local", "remote", "vni",
13815              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13816     }
13817
13818   /* Get list of vxlan-tunnel interfaces */
13819   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13820
13821   mp->sw_if_index = htonl (sw_if_index);
13822
13823   S (mp);
13824
13825   /* Use a control ping for synchronization */
13826   MPING (CONTROL_PING, mp_ping);
13827   S (mp_ping);
13828
13829   W (ret);
13830   return ret;
13831 }
13832
13833 static void vl_api_l2_fib_table_details_t_handler
13834   (vl_api_l2_fib_table_details_t * mp)
13835 {
13836   vat_main_t *vam = &vat_main;
13837
13838   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13839          "       %d       %d     %d",
13840          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13841          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13842          mp->bvi_mac);
13843 }
13844
13845 static void vl_api_l2_fib_table_details_t_handler_json
13846   (vl_api_l2_fib_table_details_t * mp)
13847 {
13848   vat_main_t *vam = &vat_main;
13849   vat_json_node_t *node = NULL;
13850
13851   if (VAT_JSON_ARRAY != vam->json_tree.type)
13852     {
13853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13854       vat_json_init_array (&vam->json_tree);
13855     }
13856   node = vat_json_array_add (&vam->json_tree);
13857
13858   vat_json_init_object (node);
13859   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13860   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13862   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13863   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13864   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13865 }
13866
13867 static int
13868 api_l2_fib_table_dump (vat_main_t * vam)
13869 {
13870   unformat_input_t *i = vam->input;
13871   vl_api_l2_fib_table_dump_t *mp;
13872   vl_api_control_ping_t *mp_ping;
13873   u32 bd_id;
13874   u8 bd_id_set = 0;
13875   int ret;
13876
13877   /* Parse args required to build the message */
13878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13879     {
13880       if (unformat (i, "bd_id %d", &bd_id))
13881         bd_id_set = 1;
13882       else
13883         break;
13884     }
13885
13886   if (bd_id_set == 0)
13887     {
13888       errmsg ("missing bridge domain");
13889       return -99;
13890     }
13891
13892   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13893
13894   /* Get list of l2 fib entries */
13895   M (L2_FIB_TABLE_DUMP, mp);
13896
13897   mp->bd_id = ntohl (bd_id);
13898   S (mp);
13899
13900   /* Use a control ping for synchronization */
13901   MPING (CONTROL_PING, mp_ping);
13902   S (mp_ping);
13903
13904   W (ret);
13905   return ret;
13906 }
13907
13908
13909 static int
13910 api_interface_name_renumber (vat_main_t * vam)
13911 {
13912   unformat_input_t *line_input = vam->input;
13913   vl_api_interface_name_renumber_t *mp;
13914   u32 sw_if_index = ~0;
13915   u32 new_show_dev_instance = ~0;
13916   int ret;
13917
13918   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13919     {
13920       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13921                     &sw_if_index))
13922         ;
13923       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13924         ;
13925       else if (unformat (line_input, "new_show_dev_instance %d",
13926                          &new_show_dev_instance))
13927         ;
13928       else
13929         break;
13930     }
13931
13932   if (sw_if_index == ~0)
13933     {
13934       errmsg ("missing interface name or sw_if_index");
13935       return -99;
13936     }
13937
13938   if (new_show_dev_instance == ~0)
13939     {
13940       errmsg ("missing new_show_dev_instance");
13941       return -99;
13942     }
13943
13944   M (INTERFACE_NAME_RENUMBER, mp);
13945
13946   mp->sw_if_index = ntohl (sw_if_index);
13947   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13948
13949   S (mp);
13950   W (ret);
13951   return ret;
13952 }
13953
13954 static int
13955 api_ip_probe_neighbor (vat_main_t * vam)
13956 {
13957   unformat_input_t *i = vam->input;
13958   vl_api_ip_probe_neighbor_t *mp;
13959   vl_api_address_t dst_adr = { };
13960   u8 int_set = 0;
13961   u8 adr_set = 0;
13962   u32 sw_if_index;
13963   int ret;
13964
13965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13968         int_set = 1;
13969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13970         int_set = 1;
13971       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13972         adr_set = 1;
13973       else
13974         break;
13975     }
13976
13977   if (int_set == 0)
13978     {
13979       errmsg ("missing interface");
13980       return -99;
13981     }
13982
13983   if (adr_set == 0)
13984     {
13985       errmsg ("missing addresses");
13986       return -99;
13987     }
13988
13989   M (IP_PROBE_NEIGHBOR, mp);
13990
13991   mp->sw_if_index = ntohl (sw_if_index);
13992   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13993
13994   S (mp);
13995   W (ret);
13996   return ret;
13997 }
13998
13999 static int
14000 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14001 {
14002   unformat_input_t *i = vam->input;
14003   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14004   u8 mode = IP_SCAN_V46_NEIGHBORS;
14005   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14006   int ret;
14007
14008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14009     {
14010       if (unformat (i, "ip4"))
14011         mode = IP_SCAN_V4_NEIGHBORS;
14012       else if (unformat (i, "ip6"))
14013         mode = IP_SCAN_V6_NEIGHBORS;
14014       if (unformat (i, "both"))
14015         mode = IP_SCAN_V46_NEIGHBORS;
14016       else if (unformat (i, "disable"))
14017         mode = IP_SCAN_DISABLED;
14018       else if (unformat (i, "interval %d", &interval))
14019         ;
14020       else if (unformat (i, "max-time %d", &time))
14021         ;
14022       else if (unformat (i, "max-update %d", &update))
14023         ;
14024       else if (unformat (i, "delay %d", &delay))
14025         ;
14026       else if (unformat (i, "stale %d", &stale))
14027         ;
14028       else
14029         break;
14030     }
14031
14032   if (interval > 255)
14033     {
14034       errmsg ("interval cannot exceed 255 minutes.");
14035       return -99;
14036     }
14037   if (time > 255)
14038     {
14039       errmsg ("max-time cannot exceed 255 usec.");
14040       return -99;
14041     }
14042   if (update > 255)
14043     {
14044       errmsg ("max-update cannot exceed 255.");
14045       return -99;
14046     }
14047   if (delay > 255)
14048     {
14049       errmsg ("delay cannot exceed 255 msec.");
14050       return -99;
14051     }
14052   if (stale > 255)
14053     {
14054       errmsg ("stale cannot exceed 255 minutes.");
14055       return -99;
14056     }
14057
14058   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14059   mp->mode = mode;
14060   mp->scan_interval = interval;
14061   mp->max_proc_time = time;
14062   mp->max_update = update;
14063   mp->scan_int_delay = delay;
14064   mp->stale_threshold = stale;
14065
14066   S (mp);
14067   W (ret);
14068   return ret;
14069 }
14070
14071 static int
14072 api_want_ip4_arp_events (vat_main_t * vam)
14073 {
14074   unformat_input_t *line_input = vam->input;
14075   vl_api_want_ip4_arp_events_t *mp;
14076   ip4_address_t address;
14077   int address_set = 0;
14078   u32 enable_disable = 1;
14079   int ret;
14080
14081   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14082     {
14083       if (unformat (line_input, "address %U", unformat_ip4_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_IP4_ARP_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_ip6_nd_events (vat_main_t * vam)
14109 {
14110   unformat_input_t *line_input = vam->input;
14111   vl_api_want_ip6_nd_events_t *mp;
14112   vl_api_ip6_address_t address;
14113   int address_set = 0;
14114   u32 enable_disable = 1;
14115   int ret;
14116
14117   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14118     {
14119       if (unformat
14120           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14121         address_set = 1;
14122       else if (unformat (line_input, "del"))
14123         enable_disable = 0;
14124       else
14125         break;
14126     }
14127
14128   if (address_set == 0)
14129     {
14130       errmsg ("missing addresses");
14131       return -99;
14132     }
14133
14134   M (WANT_IP6_ND_EVENTS, mp);
14135   mp->enable_disable = enable_disable;
14136   mp->pid = htonl (getpid ());
14137   clib_memcpy (&mp->ip, &address, sizeof (address));
14138
14139   S (mp);
14140   W (ret);
14141   return ret;
14142 }
14143
14144 static int
14145 api_want_l2_macs_events (vat_main_t * vam)
14146 {
14147   unformat_input_t *line_input = vam->input;
14148   vl_api_want_l2_macs_events_t *mp;
14149   u8 enable_disable = 1;
14150   u32 scan_delay = 0;
14151   u32 max_macs_in_event = 0;
14152   u32 learn_limit = 0;
14153   int ret;
14154
14155   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14156     {
14157       if (unformat (line_input, "learn-limit %d", &learn_limit))
14158         ;
14159       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14160         ;
14161       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14162         ;
14163       else if (unformat (line_input, "disable"))
14164         enable_disable = 0;
14165       else
14166         break;
14167     }
14168
14169   M (WANT_L2_MACS_EVENTS, mp);
14170   mp->enable_disable = enable_disable;
14171   mp->pid = htonl (getpid ());
14172   mp->learn_limit = htonl (learn_limit);
14173   mp->scan_delay = (u8) scan_delay;
14174   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14175   S (mp);
14176   W (ret);
14177   return ret;
14178 }
14179
14180 static int
14181 api_input_acl_set_interface (vat_main_t * vam)
14182 {
14183   unformat_input_t *i = vam->input;
14184   vl_api_input_acl_set_interface_t *mp;
14185   u32 sw_if_index;
14186   int sw_if_index_set;
14187   u32 ip4_table_index = ~0;
14188   u32 ip6_table_index = ~0;
14189   u32 l2_table_index = ~0;
14190   u8 is_add = 1;
14191   int ret;
14192
14193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14194     {
14195       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14196         sw_if_index_set = 1;
14197       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14198         sw_if_index_set = 1;
14199       else if (unformat (i, "del"))
14200         is_add = 0;
14201       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14202         ;
14203       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14204         ;
14205       else if (unformat (i, "l2-table %d", &l2_table_index))
14206         ;
14207       else
14208         {
14209           clib_warning ("parse error '%U'", format_unformat_error, i);
14210           return -99;
14211         }
14212     }
14213
14214   if (sw_if_index_set == 0)
14215     {
14216       errmsg ("missing interface name or sw_if_index");
14217       return -99;
14218     }
14219
14220   M (INPUT_ACL_SET_INTERFACE, mp);
14221
14222   mp->sw_if_index = ntohl (sw_if_index);
14223   mp->ip4_table_index = ntohl (ip4_table_index);
14224   mp->ip6_table_index = ntohl (ip6_table_index);
14225   mp->l2_table_index = ntohl (l2_table_index);
14226   mp->is_add = is_add;
14227
14228   S (mp);
14229   W (ret);
14230   return ret;
14231 }
14232
14233 static int
14234 api_output_acl_set_interface (vat_main_t * vam)
14235 {
14236   unformat_input_t *i = vam->input;
14237   vl_api_output_acl_set_interface_t *mp;
14238   u32 sw_if_index;
14239   int sw_if_index_set;
14240   u32 ip4_table_index = ~0;
14241   u32 ip6_table_index = ~0;
14242   u32 l2_table_index = ~0;
14243   u8 is_add = 1;
14244   int ret;
14245
14246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14249         sw_if_index_set = 1;
14250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14251         sw_if_index_set = 1;
14252       else if (unformat (i, "del"))
14253         is_add = 0;
14254       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14255         ;
14256       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14257         ;
14258       else if (unformat (i, "l2-table %d", &l2_table_index))
14259         ;
14260       else
14261         {
14262           clib_warning ("parse error '%U'", format_unformat_error, i);
14263           return -99;
14264         }
14265     }
14266
14267   if (sw_if_index_set == 0)
14268     {
14269       errmsg ("missing interface name or sw_if_index");
14270       return -99;
14271     }
14272
14273   M (OUTPUT_ACL_SET_INTERFACE, mp);
14274
14275   mp->sw_if_index = ntohl (sw_if_index);
14276   mp->ip4_table_index = ntohl (ip4_table_index);
14277   mp->ip6_table_index = ntohl (ip6_table_index);
14278   mp->l2_table_index = ntohl (l2_table_index);
14279   mp->is_add = is_add;
14280
14281   S (mp);
14282   W (ret);
14283   return ret;
14284 }
14285
14286 static int
14287 api_ip_address_dump (vat_main_t * vam)
14288 {
14289   unformat_input_t *i = vam->input;
14290   vl_api_ip_address_dump_t *mp;
14291   vl_api_control_ping_t *mp_ping;
14292   u32 sw_if_index = ~0;
14293   u8 sw_if_index_set = 0;
14294   u8 ipv4_set = 0;
14295   u8 ipv6_set = 0;
14296   int ret;
14297
14298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14299     {
14300       if (unformat (i, "sw_if_index %d", &sw_if_index))
14301         sw_if_index_set = 1;
14302       else
14303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14304         sw_if_index_set = 1;
14305       else if (unformat (i, "ipv4"))
14306         ipv4_set = 1;
14307       else if (unformat (i, "ipv6"))
14308         ipv6_set = 1;
14309       else
14310         break;
14311     }
14312
14313   if (ipv4_set && ipv6_set)
14314     {
14315       errmsg ("ipv4 and ipv6 flags cannot be both set");
14316       return -99;
14317     }
14318
14319   if ((!ipv4_set) && (!ipv6_set))
14320     {
14321       errmsg ("no ipv4 nor ipv6 flag set");
14322       return -99;
14323     }
14324
14325   if (sw_if_index_set == 0)
14326     {
14327       errmsg ("missing interface name or sw_if_index");
14328       return -99;
14329     }
14330
14331   vam->current_sw_if_index = sw_if_index;
14332   vam->is_ipv6 = ipv6_set;
14333
14334   M (IP_ADDRESS_DUMP, mp);
14335   mp->sw_if_index = ntohl (sw_if_index);
14336   mp->is_ipv6 = ipv6_set;
14337   S (mp);
14338
14339   /* Use a control ping for synchronization */
14340   MPING (CONTROL_PING, mp_ping);
14341   S (mp_ping);
14342
14343   W (ret);
14344   return ret;
14345 }
14346
14347 static int
14348 api_ip_dump (vat_main_t * vam)
14349 {
14350   vl_api_ip_dump_t *mp;
14351   vl_api_control_ping_t *mp_ping;
14352   unformat_input_t *in = vam->input;
14353   int ipv4_set = 0;
14354   int ipv6_set = 0;
14355   int is_ipv6;
14356   int i;
14357   int ret;
14358
14359   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14360     {
14361       if (unformat (in, "ipv4"))
14362         ipv4_set = 1;
14363       else if (unformat (in, "ipv6"))
14364         ipv6_set = 1;
14365       else
14366         break;
14367     }
14368
14369   if (ipv4_set && ipv6_set)
14370     {
14371       errmsg ("ipv4 and ipv6 flags cannot be both set");
14372       return -99;
14373     }
14374
14375   if ((!ipv4_set) && (!ipv6_set))
14376     {
14377       errmsg ("no ipv4 nor ipv6 flag set");
14378       return -99;
14379     }
14380
14381   is_ipv6 = ipv6_set;
14382   vam->is_ipv6 = is_ipv6;
14383
14384   /* free old data */
14385   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14386     {
14387       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14388     }
14389   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14390
14391   M (IP_DUMP, mp);
14392   mp->is_ipv6 = ipv6_set;
14393   S (mp);
14394
14395   /* Use a control ping for synchronization */
14396   MPING (CONTROL_PING, mp_ping);
14397   S (mp_ping);
14398
14399   W (ret);
14400   return ret;
14401 }
14402
14403 static int
14404 api_ipsec_spd_add_del (vat_main_t * vam)
14405 {
14406   unformat_input_t *i = vam->input;
14407   vl_api_ipsec_spd_add_del_t *mp;
14408   u32 spd_id = ~0;
14409   u8 is_add = 1;
14410   int ret;
14411
14412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (unformat (i, "spd_id %d", &spd_id))
14415         ;
14416       else if (unformat (i, "del"))
14417         is_add = 0;
14418       else
14419         {
14420           clib_warning ("parse error '%U'", format_unformat_error, i);
14421           return -99;
14422         }
14423     }
14424   if (spd_id == ~0)
14425     {
14426       errmsg ("spd_id must be set");
14427       return -99;
14428     }
14429
14430   M (IPSEC_SPD_ADD_DEL, mp);
14431
14432   mp->spd_id = ntohl (spd_id);
14433   mp->is_add = is_add;
14434
14435   S (mp);
14436   W (ret);
14437   return ret;
14438 }
14439
14440 static int
14441 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14442 {
14443   unformat_input_t *i = vam->input;
14444   vl_api_ipsec_interface_add_del_spd_t *mp;
14445   u32 sw_if_index;
14446   u8 sw_if_index_set = 0;
14447   u32 spd_id = (u32) ~ 0;
14448   u8 is_add = 1;
14449   int ret;
14450
14451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14452     {
14453       if (unformat (i, "del"))
14454         is_add = 0;
14455       else if (unformat (i, "spd_id %d", &spd_id))
14456         ;
14457       else
14458         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14459         sw_if_index_set = 1;
14460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14461         sw_if_index_set = 1;
14462       else
14463         {
14464           clib_warning ("parse error '%U'", format_unformat_error, i);
14465           return -99;
14466         }
14467
14468     }
14469
14470   if (spd_id == (u32) ~ 0)
14471     {
14472       errmsg ("spd_id must be set");
14473       return -99;
14474     }
14475
14476   if (sw_if_index_set == 0)
14477     {
14478       errmsg ("missing interface name or sw_if_index");
14479       return -99;
14480     }
14481
14482   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14483
14484   mp->spd_id = ntohl (spd_id);
14485   mp->sw_if_index = ntohl (sw_if_index);
14486   mp->is_add = is_add;
14487
14488   S (mp);
14489   W (ret);
14490   return ret;
14491 }
14492
14493 static int
14494 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14495 {
14496   unformat_input_t *i = vam->input;
14497   vl_api_ipsec_spd_entry_add_del_t *mp;
14498   u8 is_add = 1, is_outbound = 0;
14499   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14500   i32 priority = 0;
14501   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14502   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14503   vl_api_address_t laddr_start = { }, laddr_stop =
14504   {
14505   }, raddr_start =
14506   {
14507   }, raddr_stop =
14508   {
14509   };
14510   int ret;
14511
14512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14513     {
14514       if (unformat (i, "del"))
14515         is_add = 0;
14516       if (unformat (i, "outbound"))
14517         is_outbound = 1;
14518       if (unformat (i, "inbound"))
14519         is_outbound = 0;
14520       else if (unformat (i, "spd_id %d", &spd_id))
14521         ;
14522       else if (unformat (i, "sa_id %d", &sa_id))
14523         ;
14524       else if (unformat (i, "priority %d", &priority))
14525         ;
14526       else if (unformat (i, "protocol %d", &protocol))
14527         ;
14528       else if (unformat (i, "lport_start %d", &lport_start))
14529         ;
14530       else if (unformat (i, "lport_stop %d", &lport_stop))
14531         ;
14532       else if (unformat (i, "rport_start %d", &rport_start))
14533         ;
14534       else if (unformat (i, "rport_stop %d", &rport_stop))
14535         ;
14536       else if (unformat (i, "laddr_start %U",
14537                          unformat_vl_api_address, &laddr_start))
14538         ;
14539       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14540                          &laddr_stop))
14541         ;
14542       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14543                          &raddr_start))
14544         ;
14545       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14546                          &raddr_stop))
14547         ;
14548       else
14549         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14550         {
14551           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14552             {
14553               clib_warning ("unsupported action: 'resolve'");
14554               return -99;
14555             }
14556         }
14557       else
14558         {
14559           clib_warning ("parse error '%U'", format_unformat_error, i);
14560           return -99;
14561         }
14562
14563     }
14564
14565   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14566
14567   mp->is_add = is_add;
14568
14569   mp->entry.spd_id = ntohl (spd_id);
14570   mp->entry.priority = ntohl (priority);
14571   mp->entry.is_outbound = is_outbound;
14572
14573   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14574                sizeof (vl_api_address_t));
14575   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14576                sizeof (vl_api_address_t));
14577   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14578                sizeof (vl_api_address_t));
14579   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14580                sizeof (vl_api_address_t));
14581
14582   mp->entry.protocol = (u8) protocol;
14583   mp->entry.local_port_start = ntohs ((u16) lport_start);
14584   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14585   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14586   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14587   mp->entry.policy = (u8) policy;
14588   mp->entry.sa_id = ntohl (sa_id);
14589
14590   S (mp);
14591   W (ret);
14592   return ret;
14593 }
14594
14595 static int
14596 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14597 {
14598   unformat_input_t *i = vam->input;
14599   vl_api_ipsec_sad_entry_add_del_t *mp;
14600   u32 sad_id = 0, spi = 0;
14601   u8 *ck = 0, *ik = 0;
14602   u8 is_add = 1;
14603
14604   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14605   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14606   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14607   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14608   vl_api_address_t tun_src, tun_dst;
14609   int ret;
14610
14611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14612     {
14613       if (unformat (i, "del"))
14614         is_add = 0;
14615       else if (unformat (i, "sad_id %d", &sad_id))
14616         ;
14617       else if (unformat (i, "spi %d", &spi))
14618         ;
14619       else if (unformat (i, "esp"))
14620         protocol = IPSEC_API_PROTO_ESP;
14621       else
14622         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14623         {
14624           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14625           if (ADDRESS_IP6 == tun_src.af)
14626             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14627         }
14628       else
14629         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14630         {
14631           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14632           if (ADDRESS_IP6 == tun_src.af)
14633             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14634         }
14635       else
14636         if (unformat (i, "crypto_alg %U",
14637                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14638         ;
14639       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14640         ;
14641       else if (unformat (i, "integ_alg %U",
14642                          unformat_ipsec_api_integ_alg, &integ_alg))
14643         ;
14644       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14645         ;
14646       else
14647         {
14648           clib_warning ("parse error '%U'", format_unformat_error, i);
14649           return -99;
14650         }
14651
14652     }
14653
14654   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14655
14656   mp->is_add = is_add;
14657   mp->entry.sad_id = ntohl (sad_id);
14658   mp->entry.protocol = protocol;
14659   mp->entry.spi = ntohl (spi);
14660   mp->entry.flags = flags;
14661
14662   mp->entry.crypto_algorithm = crypto_alg;
14663   mp->entry.integrity_algorithm = integ_alg;
14664   mp->entry.crypto_key.length = vec_len (ck);
14665   mp->entry.integrity_key.length = vec_len (ik);
14666
14667   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14668     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14669
14670   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14671     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14672
14673   if (ck)
14674     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14675   if (ik)
14676     clib_memcpy (mp->entry.integrity_key.data, ik,
14677                  mp->entry.integrity_key.length);
14678
14679   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14680     {
14681       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14682                    sizeof (mp->entry.tunnel_src));
14683       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14684                    sizeof (mp->entry.tunnel_dst));
14685     }
14686
14687   S (mp);
14688   W (ret);
14689   return ret;
14690 }
14691
14692 static int
14693 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14694 {
14695   unformat_input_t *i = vam->input;
14696   vl_api_ipsec_tunnel_if_add_del_t *mp;
14697   u32 local_spi = 0, remote_spi = 0;
14698   u32 crypto_alg = 0, integ_alg = 0;
14699   u8 *lck = NULL, *rck = NULL;
14700   u8 *lik = NULL, *rik = NULL;
14701   vl_api_address_t local_ip = { 0 };
14702   vl_api_address_t remote_ip = { 0 };
14703   f64 before = 0;
14704   u8 is_add = 1;
14705   u8 esn = 0;
14706   u8 anti_replay = 0;
14707   u8 renumber = 0;
14708   u32 instance = ~0;
14709   u32 count = 1, jj;
14710   int ret = -1;
14711
14712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14713     {
14714       if (unformat (i, "del"))
14715         is_add = 0;
14716       else if (unformat (i, "esn"))
14717         esn = 1;
14718       else if (unformat (i, "anti-replay"))
14719         anti_replay = 1;
14720       else if (unformat (i, "count %d", &count))
14721         ;
14722       else if (unformat (i, "local_spi %d", &local_spi))
14723         ;
14724       else if (unformat (i, "remote_spi %d", &remote_spi))
14725         ;
14726       else
14727         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14728         ;
14729       else
14730         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14731         ;
14732       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14733         ;
14734       else
14735         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14736         ;
14737       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14738         ;
14739       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14740         ;
14741       else
14742         if (unformat
14743             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14744         {
14745           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14746             {
14747               errmsg ("unsupported crypto-alg: '%U'\n",
14748                       format_ipsec_crypto_alg, crypto_alg);
14749               return -99;
14750             }
14751         }
14752       else
14753         if (unformat
14754             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14755         {
14756           if (integ_alg >= IPSEC_INTEG_N_ALG)
14757             {
14758               errmsg ("unsupported integ-alg: '%U'\n",
14759                       format_ipsec_integ_alg, integ_alg);
14760               return -99;
14761             }
14762         }
14763       else if (unformat (i, "instance %u", &instance))
14764         renumber = 1;
14765       else
14766         {
14767           errmsg ("parse error '%U'\n", format_unformat_error, i);
14768           return -99;
14769         }
14770     }
14771
14772   if (count > 1)
14773     {
14774       /* Turn on async mode */
14775       vam->async_mode = 1;
14776       vam->async_errors = 0;
14777       before = vat_time_now (vam);
14778     }
14779
14780   for (jj = 0; jj < count; jj++)
14781     {
14782       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14783
14784       mp->is_add = is_add;
14785       mp->esn = esn;
14786       mp->anti_replay = anti_replay;
14787
14788       if (jj > 0)
14789         increment_address (&remote_ip);
14790
14791       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14792       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14793
14794       mp->local_spi = htonl (local_spi + jj);
14795       mp->remote_spi = htonl (remote_spi + jj);
14796       mp->crypto_alg = (u8) crypto_alg;
14797
14798       mp->local_crypto_key_len = 0;
14799       if (lck)
14800         {
14801           mp->local_crypto_key_len = vec_len (lck);
14802           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14803             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14804           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14805         }
14806
14807       mp->remote_crypto_key_len = 0;
14808       if (rck)
14809         {
14810           mp->remote_crypto_key_len = vec_len (rck);
14811           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14812             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14813           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14814         }
14815
14816       mp->integ_alg = (u8) integ_alg;
14817
14818       mp->local_integ_key_len = 0;
14819       if (lik)
14820         {
14821           mp->local_integ_key_len = vec_len (lik);
14822           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14823             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14824           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14825         }
14826
14827       mp->remote_integ_key_len = 0;
14828       if (rik)
14829         {
14830           mp->remote_integ_key_len = vec_len (rik);
14831           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14832             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14833           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14834         }
14835
14836       if (renumber)
14837         {
14838           mp->renumber = renumber;
14839           mp->show_instance = ntohl (instance);
14840         }
14841       S (mp);
14842     }
14843
14844   /* When testing multiple add/del ops, use a control-ping to sync */
14845   if (count > 1)
14846     {
14847       vl_api_control_ping_t *mp_ping;
14848       f64 after;
14849       f64 timeout;
14850
14851       /* Shut off async mode */
14852       vam->async_mode = 0;
14853
14854       MPING (CONTROL_PING, mp_ping);
14855       S (mp_ping);
14856
14857       timeout = vat_time_now (vam) + 1.0;
14858       while (vat_time_now (vam) < timeout)
14859         if (vam->result_ready == 1)
14860           goto out;
14861       vam->retval = -99;
14862
14863     out:
14864       if (vam->retval == -99)
14865         errmsg ("timeout");
14866
14867       if (vam->async_errors > 0)
14868         {
14869           errmsg ("%d asynchronous errors", vam->async_errors);
14870           vam->retval = -98;
14871         }
14872       vam->async_errors = 0;
14873       after = vat_time_now (vam);
14874
14875       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14876       if (jj > 0)
14877         count = jj;
14878
14879       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14880              count, after - before, count / (after - before));
14881     }
14882   else
14883     {
14884       /* Wait for a reply... */
14885       W (ret);
14886       return ret;
14887     }
14888
14889   return ret;
14890 }
14891
14892 static void
14893 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14894 {
14895   vat_main_t *vam = &vat_main;
14896
14897   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14898          "crypto_key %U integ_alg %u integ_key %U flags %x "
14899          "tunnel_src_addr %U tunnel_dst_addr %U "
14900          "salt %u seq_outbound %lu last_seq_inbound %lu "
14901          "replay_window %lu\n",
14902          ntohl (mp->entry.sad_id),
14903          ntohl (mp->sw_if_index),
14904          ntohl (mp->entry.spi),
14905          ntohl (mp->entry.protocol),
14906          ntohl (mp->entry.crypto_algorithm),
14907          format_hex_bytes, mp->entry.crypto_key.data,
14908          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14909          format_hex_bytes, mp->entry.integrity_key.data,
14910          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14911          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14912          &mp->entry.tunnel_dst, ntohl (mp->salt),
14913          clib_net_to_host_u64 (mp->seq_outbound),
14914          clib_net_to_host_u64 (mp->last_seq_inbound),
14915          clib_net_to_host_u64 (mp->replay_window));
14916 }
14917
14918 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14919 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14920
14921 static void vl_api_ipsec_sa_details_t_handler_json
14922   (vl_api_ipsec_sa_details_t * mp)
14923 {
14924   vat_main_t *vam = &vat_main;
14925   vat_json_node_t *node = NULL;
14926   vl_api_ipsec_sad_flags_t flags;
14927
14928   if (VAT_JSON_ARRAY != vam->json_tree.type)
14929     {
14930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14931       vat_json_init_array (&vam->json_tree);
14932     }
14933   node = vat_json_array_add (&vam->json_tree);
14934
14935   vat_json_init_object (node);
14936   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14937   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14938   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14939   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14940   vat_json_object_add_uint (node, "crypto_alg",
14941                             ntohl (mp->entry.crypto_algorithm));
14942   vat_json_object_add_uint (node, "integ_alg",
14943                             ntohl (mp->entry.integrity_algorithm));
14944   flags = ntohl (mp->entry.flags);
14945   vat_json_object_add_uint (node, "use_esn",
14946                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14947   vat_json_object_add_uint (node, "use_anti_replay",
14948                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14949   vat_json_object_add_uint (node, "is_tunnel",
14950                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14951   vat_json_object_add_uint (node, "is_tunnel_ip6",
14952                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14953   vat_json_object_add_uint (node, "udp_encap",
14954                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14955   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14956                              mp->entry.crypto_key.length);
14957   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14958                              mp->entry.integrity_key.length);
14959   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14960   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14961   vat_json_object_add_uint (node, "replay_window",
14962                             clib_net_to_host_u64 (mp->replay_window));
14963 }
14964
14965 static int
14966 api_ipsec_sa_dump (vat_main_t * vam)
14967 {
14968   unformat_input_t *i = vam->input;
14969   vl_api_ipsec_sa_dump_t *mp;
14970   vl_api_control_ping_t *mp_ping;
14971   u32 sa_id = ~0;
14972   int ret;
14973
14974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (i, "sa_id %d", &sa_id))
14977         ;
14978       else
14979         {
14980           clib_warning ("parse error '%U'", format_unformat_error, i);
14981           return -99;
14982         }
14983     }
14984
14985   M (IPSEC_SA_DUMP, mp);
14986
14987   mp->sa_id = ntohl (sa_id);
14988
14989   S (mp);
14990
14991   /* Use a control ping for synchronization */
14992   M (CONTROL_PING, mp_ping);
14993   S (mp_ping);
14994
14995   W (ret);
14996   return ret;
14997 }
14998
14999 static int
15000 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15001 {
15002   unformat_input_t *i = vam->input;
15003   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15004   u32 sw_if_index = ~0;
15005   u32 sa_id = ~0;
15006   u8 is_outbound = (u8) ~ 0;
15007   int ret;
15008
15009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15010     {
15011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15012         ;
15013       else if (unformat (i, "sa_id %d", &sa_id))
15014         ;
15015       else if (unformat (i, "outbound"))
15016         is_outbound = 1;
15017       else if (unformat (i, "inbound"))
15018         is_outbound = 0;
15019       else
15020         {
15021           clib_warning ("parse error '%U'", format_unformat_error, i);
15022           return -99;
15023         }
15024     }
15025
15026   if (sw_if_index == ~0)
15027     {
15028       errmsg ("interface must be specified");
15029       return -99;
15030     }
15031
15032   if (sa_id == ~0)
15033     {
15034       errmsg ("SA ID must be specified");
15035       return -99;
15036     }
15037
15038   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15039
15040   mp->sw_if_index = htonl (sw_if_index);
15041   mp->sa_id = htonl (sa_id);
15042   mp->is_outbound = is_outbound;
15043
15044   S (mp);
15045   W (ret);
15046
15047   return ret;
15048 }
15049
15050 static int
15051 api_get_first_msg_id (vat_main_t * vam)
15052 {
15053   vl_api_get_first_msg_id_t *mp;
15054   unformat_input_t *i = vam->input;
15055   u8 *name;
15056   u8 name_set = 0;
15057   int ret;
15058
15059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15060     {
15061       if (unformat (i, "client %s", &name))
15062         name_set = 1;
15063       else
15064         break;
15065     }
15066
15067   if (name_set == 0)
15068     {
15069       errmsg ("missing client name");
15070       return -99;
15071     }
15072   vec_add1 (name, 0);
15073
15074   if (vec_len (name) > 63)
15075     {
15076       errmsg ("client name too long");
15077       return -99;
15078     }
15079
15080   M (GET_FIRST_MSG_ID, mp);
15081   clib_memcpy (mp->name, name, vec_len (name));
15082   S (mp);
15083   W (ret);
15084   return ret;
15085 }
15086
15087 static int
15088 api_cop_interface_enable_disable (vat_main_t * vam)
15089 {
15090   unformat_input_t *line_input = vam->input;
15091   vl_api_cop_interface_enable_disable_t *mp;
15092   u32 sw_if_index = ~0;
15093   u8 enable_disable = 1;
15094   int ret;
15095
15096   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (line_input, "disable"))
15099         enable_disable = 0;
15100       if (unformat (line_input, "enable"))
15101         enable_disable = 1;
15102       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15103                          vam, &sw_if_index))
15104         ;
15105       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15106         ;
15107       else
15108         break;
15109     }
15110
15111   if (sw_if_index == ~0)
15112     {
15113       errmsg ("missing interface name or sw_if_index");
15114       return -99;
15115     }
15116
15117   /* Construct the API message */
15118   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15119   mp->sw_if_index = ntohl (sw_if_index);
15120   mp->enable_disable = enable_disable;
15121
15122   /* send it... */
15123   S (mp);
15124   /* Wait for the reply */
15125   W (ret);
15126   return ret;
15127 }
15128
15129 static int
15130 api_cop_whitelist_enable_disable (vat_main_t * vam)
15131 {
15132   unformat_input_t *line_input = vam->input;
15133   vl_api_cop_whitelist_enable_disable_t *mp;
15134   u32 sw_if_index = ~0;
15135   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15136   u32 fib_id = 0;
15137   int ret;
15138
15139   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15140     {
15141       if (unformat (line_input, "ip4"))
15142         ip4 = 1;
15143       else if (unformat (line_input, "ip6"))
15144         ip6 = 1;
15145       else if (unformat (line_input, "default"))
15146         default_cop = 1;
15147       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15148                          vam, &sw_if_index))
15149         ;
15150       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15151         ;
15152       else if (unformat (line_input, "fib-id %d", &fib_id))
15153         ;
15154       else
15155         break;
15156     }
15157
15158   if (sw_if_index == ~0)
15159     {
15160       errmsg ("missing interface name or sw_if_index");
15161       return -99;
15162     }
15163
15164   /* Construct the API message */
15165   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15166   mp->sw_if_index = ntohl (sw_if_index);
15167   mp->fib_id = ntohl (fib_id);
15168   mp->ip4 = ip4;
15169   mp->ip6 = ip6;
15170   mp->default_cop = default_cop;
15171
15172   /* send it... */
15173   S (mp);
15174   /* Wait for the reply */
15175   W (ret);
15176   return ret;
15177 }
15178
15179 static int
15180 api_get_node_graph (vat_main_t * vam)
15181 {
15182   vl_api_get_node_graph_t *mp;
15183   int ret;
15184
15185   M (GET_NODE_GRAPH, mp);
15186
15187   /* send it... */
15188   S (mp);
15189   /* Wait for the reply */
15190   W (ret);
15191   return ret;
15192 }
15193
15194 /* *INDENT-OFF* */
15195 /** Used for parsing LISP eids */
15196 typedef CLIB_PACKED(struct{
15197   u8 addr[16];   /**< eid address */
15198   u32 len;       /**< prefix length if IP */
15199   u8 type;      /**< type of eid */
15200 }) lisp_eid_vat_t;
15201 /* *INDENT-ON* */
15202
15203 static uword
15204 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15205 {
15206   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15207
15208   clib_memset (a, 0, sizeof (a[0]));
15209
15210   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15211     {
15212       a->type = 0;              /* ipv4 type */
15213     }
15214   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15215     {
15216       a->type = 1;              /* ipv6 type */
15217     }
15218   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15219     {
15220       a->type = 2;              /* mac type */
15221     }
15222   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15223     {
15224       a->type = 3;              /* NSH type */
15225       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15226       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15227     }
15228   else
15229     {
15230       return 0;
15231     }
15232
15233   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15234     {
15235       return 0;
15236     }
15237
15238   return 1;
15239 }
15240
15241 static int
15242 lisp_eid_size_vat (u8 type)
15243 {
15244   switch (type)
15245     {
15246     case 0:
15247       return 4;
15248     case 1:
15249       return 16;
15250     case 2:
15251       return 6;
15252     case 3:
15253       return 5;
15254     }
15255   return 0;
15256 }
15257
15258 static void
15259 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15260 {
15261   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15262 }
15263
15264 static int
15265 api_one_add_del_locator_set (vat_main_t * vam)
15266 {
15267   unformat_input_t *input = vam->input;
15268   vl_api_one_add_del_locator_set_t *mp;
15269   u8 is_add = 1;
15270   u8 *locator_set_name = NULL;
15271   u8 locator_set_name_set = 0;
15272   vl_api_local_locator_t locator, *locators = 0;
15273   u32 sw_if_index, priority, weight;
15274   u32 data_len = 0;
15275
15276   int ret;
15277   /* Parse args required to build the message */
15278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15279     {
15280       if (unformat (input, "del"))
15281         {
15282           is_add = 0;
15283         }
15284       else if (unformat (input, "locator-set %s", &locator_set_name))
15285         {
15286           locator_set_name_set = 1;
15287         }
15288       else if (unformat (input, "sw_if_index %u p %u w %u",
15289                          &sw_if_index, &priority, &weight))
15290         {
15291           locator.sw_if_index = htonl (sw_if_index);
15292           locator.priority = priority;
15293           locator.weight = weight;
15294           vec_add1 (locators, locator);
15295         }
15296       else
15297         if (unformat
15298             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15299              &sw_if_index, &priority, &weight))
15300         {
15301           locator.sw_if_index = htonl (sw_if_index);
15302           locator.priority = priority;
15303           locator.weight = weight;
15304           vec_add1 (locators, locator);
15305         }
15306       else
15307         break;
15308     }
15309
15310   if (locator_set_name_set == 0)
15311     {
15312       errmsg ("missing locator-set name");
15313       vec_free (locators);
15314       return -99;
15315     }
15316
15317   if (vec_len (locator_set_name) > 64)
15318     {
15319       errmsg ("locator-set name too long");
15320       vec_free (locator_set_name);
15321       vec_free (locators);
15322       return -99;
15323     }
15324   vec_add1 (locator_set_name, 0);
15325
15326   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15327
15328   /* Construct the API message */
15329   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15330
15331   mp->is_add = is_add;
15332   clib_memcpy (mp->locator_set_name, locator_set_name,
15333                vec_len (locator_set_name));
15334   vec_free (locator_set_name);
15335
15336   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15337   if (locators)
15338     clib_memcpy (mp->locators, locators, data_len);
15339   vec_free (locators);
15340
15341   /* send it... */
15342   S (mp);
15343
15344   /* Wait for a reply... */
15345   W (ret);
15346   return ret;
15347 }
15348
15349 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15350
15351 static int
15352 api_one_add_del_locator (vat_main_t * vam)
15353 {
15354   unformat_input_t *input = vam->input;
15355   vl_api_one_add_del_locator_t *mp;
15356   u32 tmp_if_index = ~0;
15357   u32 sw_if_index = ~0;
15358   u8 sw_if_index_set = 0;
15359   u8 sw_if_index_if_name_set = 0;
15360   u32 priority = ~0;
15361   u8 priority_set = 0;
15362   u32 weight = ~0;
15363   u8 weight_set = 0;
15364   u8 is_add = 1;
15365   u8 *locator_set_name = NULL;
15366   u8 locator_set_name_set = 0;
15367   int ret;
15368
15369   /* Parse args required to build the message */
15370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15371     {
15372       if (unformat (input, "del"))
15373         {
15374           is_add = 0;
15375         }
15376       else if (unformat (input, "locator-set %s", &locator_set_name))
15377         {
15378           locator_set_name_set = 1;
15379         }
15380       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15381                          &tmp_if_index))
15382         {
15383           sw_if_index_if_name_set = 1;
15384           sw_if_index = tmp_if_index;
15385         }
15386       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15387         {
15388           sw_if_index_set = 1;
15389           sw_if_index = tmp_if_index;
15390         }
15391       else if (unformat (input, "p %d", &priority))
15392         {
15393           priority_set = 1;
15394         }
15395       else if (unformat (input, "w %d", &weight))
15396         {
15397           weight_set = 1;
15398         }
15399       else
15400         break;
15401     }
15402
15403   if (locator_set_name_set == 0)
15404     {
15405       errmsg ("missing locator-set name");
15406       return -99;
15407     }
15408
15409   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15410     {
15411       errmsg ("missing sw_if_index");
15412       vec_free (locator_set_name);
15413       return -99;
15414     }
15415
15416   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15417     {
15418       errmsg ("cannot use both params interface name and sw_if_index");
15419       vec_free (locator_set_name);
15420       return -99;
15421     }
15422
15423   if (priority_set == 0)
15424     {
15425       errmsg ("missing locator-set priority");
15426       vec_free (locator_set_name);
15427       return -99;
15428     }
15429
15430   if (weight_set == 0)
15431     {
15432       errmsg ("missing locator-set weight");
15433       vec_free (locator_set_name);
15434       return -99;
15435     }
15436
15437   if (vec_len (locator_set_name) > 64)
15438     {
15439       errmsg ("locator-set name too long");
15440       vec_free (locator_set_name);
15441       return -99;
15442     }
15443   vec_add1 (locator_set_name, 0);
15444
15445   /* Construct the API message */
15446   M (ONE_ADD_DEL_LOCATOR, mp);
15447
15448   mp->is_add = is_add;
15449   mp->sw_if_index = ntohl (sw_if_index);
15450   mp->priority = priority;
15451   mp->weight = weight;
15452   clib_memcpy (mp->locator_set_name, locator_set_name,
15453                vec_len (locator_set_name));
15454   vec_free (locator_set_name);
15455
15456   /* send it... */
15457   S (mp);
15458
15459   /* Wait for a reply... */
15460   W (ret);
15461   return ret;
15462 }
15463
15464 #define api_lisp_add_del_locator api_one_add_del_locator
15465
15466 uword
15467 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15468 {
15469   u32 *key_id = va_arg (*args, u32 *);
15470   u8 *s = 0;
15471
15472   if (unformat (input, "%s", &s))
15473     {
15474       if (!strcmp ((char *) s, "sha1"))
15475         key_id[0] = HMAC_SHA_1_96;
15476       else if (!strcmp ((char *) s, "sha256"))
15477         key_id[0] = HMAC_SHA_256_128;
15478       else
15479         {
15480           clib_warning ("invalid key_id: '%s'", s);
15481           key_id[0] = HMAC_NO_KEY;
15482         }
15483     }
15484   else
15485     return 0;
15486
15487   vec_free (s);
15488   return 1;
15489 }
15490
15491 static int
15492 api_one_add_del_local_eid (vat_main_t * vam)
15493 {
15494   unformat_input_t *input = vam->input;
15495   vl_api_one_add_del_local_eid_t *mp;
15496   u8 is_add = 1;
15497   u8 eid_set = 0;
15498   lisp_eid_vat_t _eid, *eid = &_eid;
15499   u8 *locator_set_name = 0;
15500   u8 locator_set_name_set = 0;
15501   u32 vni = 0;
15502   u16 key_id = 0;
15503   u8 *key = 0;
15504   int ret;
15505
15506   /* Parse args required to build the message */
15507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (input, "del"))
15510         {
15511           is_add = 0;
15512         }
15513       else if (unformat (input, "vni %d", &vni))
15514         {
15515           ;
15516         }
15517       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15518         {
15519           eid_set = 1;
15520         }
15521       else if (unformat (input, "locator-set %s", &locator_set_name))
15522         {
15523           locator_set_name_set = 1;
15524         }
15525       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15526         ;
15527       else if (unformat (input, "secret-key %_%v%_", &key))
15528         ;
15529       else
15530         break;
15531     }
15532
15533   if (locator_set_name_set == 0)
15534     {
15535       errmsg ("missing locator-set name");
15536       return -99;
15537     }
15538
15539   if (0 == eid_set)
15540     {
15541       errmsg ("EID address not set!");
15542       vec_free (locator_set_name);
15543       return -99;
15544     }
15545
15546   if (key && (0 == key_id))
15547     {
15548       errmsg ("invalid key_id!");
15549       return -99;
15550     }
15551
15552   if (vec_len (key) > 64)
15553     {
15554       errmsg ("key too long");
15555       vec_free (key);
15556       return -99;
15557     }
15558
15559   if (vec_len (locator_set_name) > 64)
15560     {
15561       errmsg ("locator-set name too long");
15562       vec_free (locator_set_name);
15563       return -99;
15564     }
15565   vec_add1 (locator_set_name, 0);
15566
15567   /* Construct the API message */
15568   M (ONE_ADD_DEL_LOCAL_EID, mp);
15569
15570   mp->is_add = is_add;
15571   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15572   mp->eid_type = eid->type;
15573   mp->prefix_len = eid->len;
15574   mp->vni = clib_host_to_net_u32 (vni);
15575   mp->key_id = clib_host_to_net_u16 (key_id);
15576   clib_memcpy (mp->locator_set_name, locator_set_name,
15577                vec_len (locator_set_name));
15578   clib_memcpy (mp->key, key, vec_len (key));
15579
15580   vec_free (locator_set_name);
15581   vec_free (key);
15582
15583   /* send it... */
15584   S (mp);
15585
15586   /* Wait for a reply... */
15587   W (ret);
15588   return ret;
15589 }
15590
15591 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15592
15593 static int
15594 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15595 {
15596   u32 dp_table = 0, vni = 0;;
15597   unformat_input_t *input = vam->input;
15598   vl_api_gpe_add_del_fwd_entry_t *mp;
15599   u8 is_add = 1;
15600   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15601   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15602   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15603   u32 action = ~0, w;
15604   ip4_address_t rmt_rloc4, lcl_rloc4;
15605   ip6_address_t rmt_rloc6, lcl_rloc6;
15606   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15607   int ret;
15608
15609   clib_memset (&rloc, 0, sizeof (rloc));
15610
15611   /* Parse args required to build the message */
15612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15613     {
15614       if (unformat (input, "del"))
15615         is_add = 0;
15616       else if (unformat (input, "add"))
15617         is_add = 1;
15618       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15619         {
15620           rmt_eid_set = 1;
15621         }
15622       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15623         {
15624           lcl_eid_set = 1;
15625         }
15626       else if (unformat (input, "vrf %d", &dp_table))
15627         ;
15628       else if (unformat (input, "bd %d", &dp_table))
15629         ;
15630       else if (unformat (input, "vni %d", &vni))
15631         ;
15632       else if (unformat (input, "w %d", &w))
15633         {
15634           if (!curr_rloc)
15635             {
15636               errmsg ("No RLOC configured for setting priority/weight!");
15637               return -99;
15638             }
15639           curr_rloc->weight = w;
15640         }
15641       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15642                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15643         {
15644           rloc.is_ip4 = 1;
15645
15646           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15647           rloc.weight = 0;
15648           vec_add1 (lcl_locs, rloc);
15649
15650           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15651           vec_add1 (rmt_locs, rloc);
15652           /* weight saved in rmt loc */
15653           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15654         }
15655       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15656                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15657         {
15658           rloc.is_ip4 = 0;
15659           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15660           rloc.weight = 0;
15661           vec_add1 (lcl_locs, rloc);
15662
15663           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15664           vec_add1 (rmt_locs, rloc);
15665           /* weight saved in rmt loc */
15666           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15667         }
15668       else if (unformat (input, "action %d", &action))
15669         {
15670           ;
15671         }
15672       else
15673         {
15674           clib_warning ("parse error '%U'", format_unformat_error, input);
15675           return -99;
15676         }
15677     }
15678
15679   if (!rmt_eid_set)
15680     {
15681       errmsg ("remote eid addresses not set");
15682       return -99;
15683     }
15684
15685   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15686     {
15687       errmsg ("eid types don't match");
15688       return -99;
15689     }
15690
15691   if (0 == rmt_locs && (u32) ~ 0 == action)
15692     {
15693       errmsg ("action not set for negative mapping");
15694       return -99;
15695     }
15696
15697   /* Construct the API message */
15698   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15699       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15700
15701   mp->is_add = is_add;
15702   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15703   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15704   mp->eid_type = rmt_eid->type;
15705   mp->dp_table = clib_host_to_net_u32 (dp_table);
15706   mp->vni = clib_host_to_net_u32 (vni);
15707   mp->rmt_len = rmt_eid->len;
15708   mp->lcl_len = lcl_eid->len;
15709   mp->action = action;
15710
15711   if (0 != rmt_locs && 0 != lcl_locs)
15712     {
15713       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15714       clib_memcpy (mp->locs, lcl_locs,
15715                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15716
15717       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15718       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15719                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15720     }
15721   vec_free (lcl_locs);
15722   vec_free (rmt_locs);
15723
15724   /* send it... */
15725   S (mp);
15726
15727   /* Wait for a reply... */
15728   W (ret);
15729   return ret;
15730 }
15731
15732 static int
15733 api_one_add_del_map_server (vat_main_t * vam)
15734 {
15735   unformat_input_t *input = vam->input;
15736   vl_api_one_add_del_map_server_t *mp;
15737   u8 is_add = 1;
15738   u8 ipv4_set = 0;
15739   u8 ipv6_set = 0;
15740   ip4_address_t ipv4;
15741   ip6_address_t ipv6;
15742   int ret;
15743
15744   /* Parse args required to build the message */
15745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15746     {
15747       if (unformat (input, "del"))
15748         {
15749           is_add = 0;
15750         }
15751       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15752         {
15753           ipv4_set = 1;
15754         }
15755       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15756         {
15757           ipv6_set = 1;
15758         }
15759       else
15760         break;
15761     }
15762
15763   if (ipv4_set && ipv6_set)
15764     {
15765       errmsg ("both eid v4 and v6 addresses set");
15766       return -99;
15767     }
15768
15769   if (!ipv4_set && !ipv6_set)
15770     {
15771       errmsg ("eid addresses not set");
15772       return -99;
15773     }
15774
15775   /* Construct the API message */
15776   M (ONE_ADD_DEL_MAP_SERVER, mp);
15777
15778   mp->is_add = is_add;
15779   if (ipv6_set)
15780     {
15781       mp->is_ipv6 = 1;
15782       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15783     }
15784   else
15785     {
15786       mp->is_ipv6 = 0;
15787       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15788     }
15789
15790   /* send it... */
15791   S (mp);
15792
15793   /* Wait for a reply... */
15794   W (ret);
15795   return ret;
15796 }
15797
15798 #define api_lisp_add_del_map_server api_one_add_del_map_server
15799
15800 static int
15801 api_one_add_del_map_resolver (vat_main_t * vam)
15802 {
15803   unformat_input_t *input = vam->input;
15804   vl_api_one_add_del_map_resolver_t *mp;
15805   u8 is_add = 1;
15806   u8 ipv4_set = 0;
15807   u8 ipv6_set = 0;
15808   ip4_address_t ipv4;
15809   ip6_address_t ipv6;
15810   int ret;
15811
15812   /* Parse args required to build the message */
15813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15814     {
15815       if (unformat (input, "del"))
15816         {
15817           is_add = 0;
15818         }
15819       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15820         {
15821           ipv4_set = 1;
15822         }
15823       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15824         {
15825           ipv6_set = 1;
15826         }
15827       else
15828         break;
15829     }
15830
15831   if (ipv4_set && ipv6_set)
15832     {
15833       errmsg ("both eid v4 and v6 addresses set");
15834       return -99;
15835     }
15836
15837   if (!ipv4_set && !ipv6_set)
15838     {
15839       errmsg ("eid addresses not set");
15840       return -99;
15841     }
15842
15843   /* Construct the API message */
15844   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15845
15846   mp->is_add = is_add;
15847   if (ipv6_set)
15848     {
15849       mp->is_ipv6 = 1;
15850       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15851     }
15852   else
15853     {
15854       mp->is_ipv6 = 0;
15855       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15856     }
15857
15858   /* send it... */
15859   S (mp);
15860
15861   /* Wait for a reply... */
15862   W (ret);
15863   return ret;
15864 }
15865
15866 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15867
15868 static int
15869 api_lisp_gpe_enable_disable (vat_main_t * vam)
15870 {
15871   unformat_input_t *input = vam->input;
15872   vl_api_gpe_enable_disable_t *mp;
15873   u8 is_set = 0;
15874   u8 is_en = 1;
15875   int ret;
15876
15877   /* Parse args required to build the message */
15878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15879     {
15880       if (unformat (input, "enable"))
15881         {
15882           is_set = 1;
15883           is_en = 1;
15884         }
15885       else if (unformat (input, "disable"))
15886         {
15887           is_set = 1;
15888           is_en = 0;
15889         }
15890       else
15891         break;
15892     }
15893
15894   if (is_set == 0)
15895     {
15896       errmsg ("Value not set");
15897       return -99;
15898     }
15899
15900   /* Construct the API message */
15901   M (GPE_ENABLE_DISABLE, mp);
15902
15903   mp->is_en = is_en;
15904
15905   /* send it... */
15906   S (mp);
15907
15908   /* Wait for a reply... */
15909   W (ret);
15910   return ret;
15911 }
15912
15913 static int
15914 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15915 {
15916   unformat_input_t *input = vam->input;
15917   vl_api_one_rloc_probe_enable_disable_t *mp;
15918   u8 is_set = 0;
15919   u8 is_en = 0;
15920   int ret;
15921
15922   /* Parse args required to build the message */
15923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15924     {
15925       if (unformat (input, "enable"))
15926         {
15927           is_set = 1;
15928           is_en = 1;
15929         }
15930       else if (unformat (input, "disable"))
15931         is_set = 1;
15932       else
15933         break;
15934     }
15935
15936   if (!is_set)
15937     {
15938       errmsg ("Value not set");
15939       return -99;
15940     }
15941
15942   /* Construct the API message */
15943   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15944
15945   mp->is_enabled = is_en;
15946
15947   /* send it... */
15948   S (mp);
15949
15950   /* Wait for a reply... */
15951   W (ret);
15952   return ret;
15953 }
15954
15955 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15956
15957 static int
15958 api_one_map_register_enable_disable (vat_main_t * vam)
15959 {
15960   unformat_input_t *input = vam->input;
15961   vl_api_one_map_register_enable_disable_t *mp;
15962   u8 is_set = 0;
15963   u8 is_en = 0;
15964   int ret;
15965
15966   /* Parse args required to build the message */
15967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15968     {
15969       if (unformat (input, "enable"))
15970         {
15971           is_set = 1;
15972           is_en = 1;
15973         }
15974       else if (unformat (input, "disable"))
15975         is_set = 1;
15976       else
15977         break;
15978     }
15979
15980   if (!is_set)
15981     {
15982       errmsg ("Value not set");
15983       return -99;
15984     }
15985
15986   /* Construct the API message */
15987   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15988
15989   mp->is_enabled = is_en;
15990
15991   /* send it... */
15992   S (mp);
15993
15994   /* Wait for a reply... */
15995   W (ret);
15996   return ret;
15997 }
15998
15999 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16000
16001 static int
16002 api_one_enable_disable (vat_main_t * vam)
16003 {
16004   unformat_input_t *input = vam->input;
16005   vl_api_one_enable_disable_t *mp;
16006   u8 is_set = 0;
16007   u8 is_en = 0;
16008   int ret;
16009
16010   /* Parse args required to build the message */
16011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16012     {
16013       if (unformat (input, "enable"))
16014         {
16015           is_set = 1;
16016           is_en = 1;
16017         }
16018       else if (unformat (input, "disable"))
16019         {
16020           is_set = 1;
16021         }
16022       else
16023         break;
16024     }
16025
16026   if (!is_set)
16027     {
16028       errmsg ("Value not set");
16029       return -99;
16030     }
16031
16032   /* Construct the API message */
16033   M (ONE_ENABLE_DISABLE, mp);
16034
16035   mp->is_en = is_en;
16036
16037   /* send it... */
16038   S (mp);
16039
16040   /* Wait for a reply... */
16041   W (ret);
16042   return ret;
16043 }
16044
16045 #define api_lisp_enable_disable api_one_enable_disable
16046
16047 static int
16048 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16049 {
16050   unformat_input_t *input = vam->input;
16051   vl_api_one_enable_disable_xtr_mode_t *mp;
16052   u8 is_set = 0;
16053   u8 is_en = 0;
16054   int ret;
16055
16056   /* Parse args required to build the message */
16057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16058     {
16059       if (unformat (input, "enable"))
16060         {
16061           is_set = 1;
16062           is_en = 1;
16063         }
16064       else if (unformat (input, "disable"))
16065         {
16066           is_set = 1;
16067         }
16068       else
16069         break;
16070     }
16071
16072   if (!is_set)
16073     {
16074       errmsg ("Value not set");
16075       return -99;
16076     }
16077
16078   /* Construct the API message */
16079   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16080
16081   mp->is_en = is_en;
16082
16083   /* send it... */
16084   S (mp);
16085
16086   /* Wait for a reply... */
16087   W (ret);
16088   return ret;
16089 }
16090
16091 static int
16092 api_one_show_xtr_mode (vat_main_t * vam)
16093 {
16094   vl_api_one_show_xtr_mode_t *mp;
16095   int ret;
16096
16097   /* Construct the API message */
16098   M (ONE_SHOW_XTR_MODE, mp);
16099
16100   /* send it... */
16101   S (mp);
16102
16103   /* Wait for a reply... */
16104   W (ret);
16105   return ret;
16106 }
16107
16108 static int
16109 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16110 {
16111   unformat_input_t *input = vam->input;
16112   vl_api_one_enable_disable_pitr_mode_t *mp;
16113   u8 is_set = 0;
16114   u8 is_en = 0;
16115   int ret;
16116
16117   /* Parse args required to build the message */
16118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16119     {
16120       if (unformat (input, "enable"))
16121         {
16122           is_set = 1;
16123           is_en = 1;
16124         }
16125       else if (unformat (input, "disable"))
16126         {
16127           is_set = 1;
16128         }
16129       else
16130         break;
16131     }
16132
16133   if (!is_set)
16134     {
16135       errmsg ("Value not set");
16136       return -99;
16137     }
16138
16139   /* Construct the API message */
16140   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16141
16142   mp->is_en = is_en;
16143
16144   /* send it... */
16145   S (mp);
16146
16147   /* Wait for a reply... */
16148   W (ret);
16149   return ret;
16150 }
16151
16152 static int
16153 api_one_show_pitr_mode (vat_main_t * vam)
16154 {
16155   vl_api_one_show_pitr_mode_t *mp;
16156   int ret;
16157
16158   /* Construct the API message */
16159   M (ONE_SHOW_PITR_MODE, mp);
16160
16161   /* send it... */
16162   S (mp);
16163
16164   /* Wait for a reply... */
16165   W (ret);
16166   return ret;
16167 }
16168
16169 static int
16170 api_one_enable_disable_petr_mode (vat_main_t * vam)
16171 {
16172   unformat_input_t *input = vam->input;
16173   vl_api_one_enable_disable_petr_mode_t *mp;
16174   u8 is_set = 0;
16175   u8 is_en = 0;
16176   int ret;
16177
16178   /* Parse args required to build the message */
16179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16180     {
16181       if (unformat (input, "enable"))
16182         {
16183           is_set = 1;
16184           is_en = 1;
16185         }
16186       else if (unformat (input, "disable"))
16187         {
16188           is_set = 1;
16189         }
16190       else
16191         break;
16192     }
16193
16194   if (!is_set)
16195     {
16196       errmsg ("Value not set");
16197       return -99;
16198     }
16199
16200   /* Construct the API message */
16201   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16202
16203   mp->is_en = is_en;
16204
16205   /* send it... */
16206   S (mp);
16207
16208   /* Wait for a reply... */
16209   W (ret);
16210   return ret;
16211 }
16212
16213 static int
16214 api_one_show_petr_mode (vat_main_t * vam)
16215 {
16216   vl_api_one_show_petr_mode_t *mp;
16217   int ret;
16218
16219   /* Construct the API message */
16220   M (ONE_SHOW_PETR_MODE, mp);
16221
16222   /* send it... */
16223   S (mp);
16224
16225   /* Wait for a reply... */
16226   W (ret);
16227   return ret;
16228 }
16229
16230 static int
16231 api_show_one_map_register_state (vat_main_t * vam)
16232 {
16233   vl_api_show_one_map_register_state_t *mp;
16234   int ret;
16235
16236   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16237
16238   /* send */
16239   S (mp);
16240
16241   /* wait for reply */
16242   W (ret);
16243   return ret;
16244 }
16245
16246 #define api_show_lisp_map_register_state api_show_one_map_register_state
16247
16248 static int
16249 api_show_one_rloc_probe_state (vat_main_t * vam)
16250 {
16251   vl_api_show_one_rloc_probe_state_t *mp;
16252   int ret;
16253
16254   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16255
16256   /* send */
16257   S (mp);
16258
16259   /* wait for reply */
16260   W (ret);
16261   return ret;
16262 }
16263
16264 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16265
16266 static int
16267 api_one_add_del_ndp_entry (vat_main_t * vam)
16268 {
16269   vl_api_one_add_del_ndp_entry_t *mp;
16270   unformat_input_t *input = vam->input;
16271   u8 is_add = 1;
16272   u8 mac_set = 0;
16273   u8 bd_set = 0;
16274   u8 ip_set = 0;
16275   u8 mac[6] = { 0, };
16276   u8 ip6[16] = { 0, };
16277   u32 bd = ~0;
16278   int ret;
16279
16280   /* Parse args required to build the message */
16281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16282     {
16283       if (unformat (input, "del"))
16284         is_add = 0;
16285       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16286         mac_set = 1;
16287       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16288         ip_set = 1;
16289       else if (unformat (input, "bd %d", &bd))
16290         bd_set = 1;
16291       else
16292         {
16293           errmsg ("parse error '%U'", format_unformat_error, input);
16294           return -99;
16295         }
16296     }
16297
16298   if (!bd_set || !ip_set || (!mac_set && is_add))
16299     {
16300       errmsg ("Missing BD, IP or MAC!");
16301       return -99;
16302     }
16303
16304   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16305   mp->is_add = is_add;
16306   clib_memcpy (mp->mac, mac, 6);
16307   mp->bd = clib_host_to_net_u32 (bd);
16308   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16309
16310   /* send */
16311   S (mp);
16312
16313   /* wait for reply */
16314   W (ret);
16315   return ret;
16316 }
16317
16318 static int
16319 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16320 {
16321   vl_api_one_add_del_l2_arp_entry_t *mp;
16322   unformat_input_t *input = vam->input;
16323   u8 is_add = 1;
16324   u8 mac_set = 0;
16325   u8 bd_set = 0;
16326   u8 ip_set = 0;
16327   u8 mac[6] = { 0, };
16328   u32 ip4 = 0, bd = ~0;
16329   int ret;
16330
16331   /* Parse args required to build the message */
16332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16333     {
16334       if (unformat (input, "del"))
16335         is_add = 0;
16336       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16337         mac_set = 1;
16338       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16339         ip_set = 1;
16340       else if (unformat (input, "bd %d", &bd))
16341         bd_set = 1;
16342       else
16343         {
16344           errmsg ("parse error '%U'", format_unformat_error, input);
16345           return -99;
16346         }
16347     }
16348
16349   if (!bd_set || !ip_set || (!mac_set && is_add))
16350     {
16351       errmsg ("Missing BD, IP or MAC!");
16352       return -99;
16353     }
16354
16355   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16356   mp->is_add = is_add;
16357   clib_memcpy (mp->mac, mac, 6);
16358   mp->bd = clib_host_to_net_u32 (bd);
16359   mp->ip4 = ip4;
16360
16361   /* send */
16362   S (mp);
16363
16364   /* wait for reply */
16365   W (ret);
16366   return ret;
16367 }
16368
16369 static int
16370 api_one_ndp_bd_get (vat_main_t * vam)
16371 {
16372   vl_api_one_ndp_bd_get_t *mp;
16373   int ret;
16374
16375   M (ONE_NDP_BD_GET, mp);
16376
16377   /* send */
16378   S (mp);
16379
16380   /* wait for reply */
16381   W (ret);
16382   return ret;
16383 }
16384
16385 static int
16386 api_one_ndp_entries_get (vat_main_t * vam)
16387 {
16388   vl_api_one_ndp_entries_get_t *mp;
16389   unformat_input_t *input = vam->input;
16390   u8 bd_set = 0;
16391   u32 bd = ~0;
16392   int ret;
16393
16394   /* Parse args required to build the message */
16395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16396     {
16397       if (unformat (input, "bd %d", &bd))
16398         bd_set = 1;
16399       else
16400         {
16401           errmsg ("parse error '%U'", format_unformat_error, input);
16402           return -99;
16403         }
16404     }
16405
16406   if (!bd_set)
16407     {
16408       errmsg ("Expected bridge domain!");
16409       return -99;
16410     }
16411
16412   M (ONE_NDP_ENTRIES_GET, mp);
16413   mp->bd = clib_host_to_net_u32 (bd);
16414
16415   /* send */
16416   S (mp);
16417
16418   /* wait for reply */
16419   W (ret);
16420   return ret;
16421 }
16422
16423 static int
16424 api_one_l2_arp_bd_get (vat_main_t * vam)
16425 {
16426   vl_api_one_l2_arp_bd_get_t *mp;
16427   int ret;
16428
16429   M (ONE_L2_ARP_BD_GET, mp);
16430
16431   /* send */
16432   S (mp);
16433
16434   /* wait for reply */
16435   W (ret);
16436   return ret;
16437 }
16438
16439 static int
16440 api_one_l2_arp_entries_get (vat_main_t * vam)
16441 {
16442   vl_api_one_l2_arp_entries_get_t *mp;
16443   unformat_input_t *input = vam->input;
16444   u8 bd_set = 0;
16445   u32 bd = ~0;
16446   int ret;
16447
16448   /* Parse args required to build the message */
16449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (input, "bd %d", &bd))
16452         bd_set = 1;
16453       else
16454         {
16455           errmsg ("parse error '%U'", format_unformat_error, input);
16456           return -99;
16457         }
16458     }
16459
16460   if (!bd_set)
16461     {
16462       errmsg ("Expected bridge domain!");
16463       return -99;
16464     }
16465
16466   M (ONE_L2_ARP_ENTRIES_GET, mp);
16467   mp->bd = clib_host_to_net_u32 (bd);
16468
16469   /* send */
16470   S (mp);
16471
16472   /* wait for reply */
16473   W (ret);
16474   return ret;
16475 }
16476
16477 static int
16478 api_one_stats_enable_disable (vat_main_t * vam)
16479 {
16480   vl_api_one_stats_enable_disable_t *mp;
16481   unformat_input_t *input = vam->input;
16482   u8 is_set = 0;
16483   u8 is_en = 0;
16484   int ret;
16485
16486   /* Parse args required to build the message */
16487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16488     {
16489       if (unformat (input, "enable"))
16490         {
16491           is_set = 1;
16492           is_en = 1;
16493         }
16494       else if (unformat (input, "disable"))
16495         {
16496           is_set = 1;
16497         }
16498       else
16499         break;
16500     }
16501
16502   if (!is_set)
16503     {
16504       errmsg ("Value not set");
16505       return -99;
16506     }
16507
16508   M (ONE_STATS_ENABLE_DISABLE, mp);
16509   mp->is_en = is_en;
16510
16511   /* send */
16512   S (mp);
16513
16514   /* wait for reply */
16515   W (ret);
16516   return ret;
16517 }
16518
16519 static int
16520 api_show_one_stats_enable_disable (vat_main_t * vam)
16521 {
16522   vl_api_show_one_stats_enable_disable_t *mp;
16523   int ret;
16524
16525   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16526
16527   /* send */
16528   S (mp);
16529
16530   /* wait for reply */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 static int
16536 api_show_one_map_request_mode (vat_main_t * vam)
16537 {
16538   vl_api_show_one_map_request_mode_t *mp;
16539   int ret;
16540
16541   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16542
16543   /* send */
16544   S (mp);
16545
16546   /* wait for reply */
16547   W (ret);
16548   return ret;
16549 }
16550
16551 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16552
16553 static int
16554 api_one_map_request_mode (vat_main_t * vam)
16555 {
16556   unformat_input_t *input = vam->input;
16557   vl_api_one_map_request_mode_t *mp;
16558   u8 mode = 0;
16559   int ret;
16560
16561   /* Parse args required to build the message */
16562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16563     {
16564       if (unformat (input, "dst-only"))
16565         mode = 0;
16566       else if (unformat (input, "src-dst"))
16567         mode = 1;
16568       else
16569         {
16570           errmsg ("parse error '%U'", format_unformat_error, input);
16571           return -99;
16572         }
16573     }
16574
16575   M (ONE_MAP_REQUEST_MODE, mp);
16576
16577   mp->mode = mode;
16578
16579   /* send */
16580   S (mp);
16581
16582   /* wait for reply */
16583   W (ret);
16584   return ret;
16585 }
16586
16587 #define api_lisp_map_request_mode api_one_map_request_mode
16588
16589 /**
16590  * Enable/disable ONE proxy ITR.
16591  *
16592  * @param vam vpp API test context
16593  * @return return code
16594  */
16595 static int
16596 api_one_pitr_set_locator_set (vat_main_t * vam)
16597 {
16598   u8 ls_name_set = 0;
16599   unformat_input_t *input = vam->input;
16600   vl_api_one_pitr_set_locator_set_t *mp;
16601   u8 is_add = 1;
16602   u8 *ls_name = 0;
16603   int ret;
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "del"))
16609         is_add = 0;
16610       else if (unformat (input, "locator-set %s", &ls_name))
16611         ls_name_set = 1;
16612       else
16613         {
16614           errmsg ("parse error '%U'", format_unformat_error, input);
16615           return -99;
16616         }
16617     }
16618
16619   if (!ls_name_set)
16620     {
16621       errmsg ("locator-set name not set!");
16622       return -99;
16623     }
16624
16625   M (ONE_PITR_SET_LOCATOR_SET, mp);
16626
16627   mp->is_add = is_add;
16628   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16629   vec_free (ls_name);
16630
16631   /* send */
16632   S (mp);
16633
16634   /* wait for reply */
16635   W (ret);
16636   return ret;
16637 }
16638
16639 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16640
16641 static int
16642 api_one_nsh_set_locator_set (vat_main_t * vam)
16643 {
16644   u8 ls_name_set = 0;
16645   unformat_input_t *input = vam->input;
16646   vl_api_one_nsh_set_locator_set_t *mp;
16647   u8 is_add = 1;
16648   u8 *ls_name = 0;
16649   int ret;
16650
16651   /* Parse args required to build the message */
16652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16653     {
16654       if (unformat (input, "del"))
16655         is_add = 0;
16656       else if (unformat (input, "ls %s", &ls_name))
16657         ls_name_set = 1;
16658       else
16659         {
16660           errmsg ("parse error '%U'", format_unformat_error, input);
16661           return -99;
16662         }
16663     }
16664
16665   if (!ls_name_set && is_add)
16666     {
16667       errmsg ("locator-set name not set!");
16668       return -99;
16669     }
16670
16671   M (ONE_NSH_SET_LOCATOR_SET, mp);
16672
16673   mp->is_add = is_add;
16674   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16675   vec_free (ls_name);
16676
16677   /* send */
16678   S (mp);
16679
16680   /* wait for reply */
16681   W (ret);
16682   return ret;
16683 }
16684
16685 static int
16686 api_show_one_pitr (vat_main_t * vam)
16687 {
16688   vl_api_show_one_pitr_t *mp;
16689   int ret;
16690
16691   if (!vam->json_output)
16692     {
16693       print (vam->ofp, "%=20s", "lisp status:");
16694     }
16695
16696   M (SHOW_ONE_PITR, mp);
16697   /* send it... */
16698   S (mp);
16699
16700   /* Wait for a reply... */
16701   W (ret);
16702   return ret;
16703 }
16704
16705 #define api_show_lisp_pitr api_show_one_pitr
16706
16707 static int
16708 api_one_use_petr (vat_main_t * vam)
16709 {
16710   unformat_input_t *input = vam->input;
16711   vl_api_one_use_petr_t *mp;
16712   u8 is_add = 0;
16713   ip_address_t ip;
16714   int ret;
16715
16716   clib_memset (&ip, 0, sizeof (ip));
16717
16718   /* Parse args required to build the message */
16719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16720     {
16721       if (unformat (input, "disable"))
16722         is_add = 0;
16723       else
16724         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16725         {
16726           is_add = 1;
16727           ip_addr_version (&ip) = IP4;
16728         }
16729       else
16730         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16731         {
16732           is_add = 1;
16733           ip_addr_version (&ip) = IP6;
16734         }
16735       else
16736         {
16737           errmsg ("parse error '%U'", format_unformat_error, input);
16738           return -99;
16739         }
16740     }
16741
16742   M (ONE_USE_PETR, mp);
16743
16744   mp->is_add = is_add;
16745   if (is_add)
16746     {
16747       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16748       if (mp->is_ip4)
16749         clib_memcpy (mp->address, &ip, 4);
16750       else
16751         clib_memcpy (mp->address, &ip, 16);
16752     }
16753
16754   /* send */
16755   S (mp);
16756
16757   /* wait for reply */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 #define api_lisp_use_petr api_one_use_petr
16763
16764 static int
16765 api_show_one_nsh_mapping (vat_main_t * vam)
16766 {
16767   vl_api_show_one_use_petr_t *mp;
16768   int ret;
16769
16770   if (!vam->json_output)
16771     {
16772       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16773     }
16774
16775   M (SHOW_ONE_NSH_MAPPING, mp);
16776   /* send it... */
16777   S (mp);
16778
16779   /* Wait for a reply... */
16780   W (ret);
16781   return ret;
16782 }
16783
16784 static int
16785 api_show_one_use_petr (vat_main_t * vam)
16786 {
16787   vl_api_show_one_use_petr_t *mp;
16788   int ret;
16789
16790   if (!vam->json_output)
16791     {
16792       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16793     }
16794
16795   M (SHOW_ONE_USE_PETR, mp);
16796   /* send it... */
16797   S (mp);
16798
16799   /* Wait for a reply... */
16800   W (ret);
16801   return ret;
16802 }
16803
16804 #define api_show_lisp_use_petr api_show_one_use_petr
16805
16806 /**
16807  * Add/delete mapping between vni and vrf
16808  */
16809 static int
16810 api_one_eid_table_add_del_map (vat_main_t * vam)
16811 {
16812   unformat_input_t *input = vam->input;
16813   vl_api_one_eid_table_add_del_map_t *mp;
16814   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16815   u32 vni, vrf, bd_index;
16816   int ret;
16817
16818   /* Parse args required to build the message */
16819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16820     {
16821       if (unformat (input, "del"))
16822         is_add = 0;
16823       else if (unformat (input, "vrf %d", &vrf))
16824         vrf_set = 1;
16825       else if (unformat (input, "bd_index %d", &bd_index))
16826         bd_index_set = 1;
16827       else if (unformat (input, "vni %d", &vni))
16828         vni_set = 1;
16829       else
16830         break;
16831     }
16832
16833   if (!vni_set || (!vrf_set && !bd_index_set))
16834     {
16835       errmsg ("missing arguments!");
16836       return -99;
16837     }
16838
16839   if (vrf_set && bd_index_set)
16840     {
16841       errmsg ("error: both vrf and bd entered!");
16842       return -99;
16843     }
16844
16845   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16846
16847   mp->is_add = is_add;
16848   mp->vni = htonl (vni);
16849   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16850   mp->is_l2 = bd_index_set;
16851
16852   /* send */
16853   S (mp);
16854
16855   /* wait for reply */
16856   W (ret);
16857   return ret;
16858 }
16859
16860 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16861
16862 uword
16863 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16864 {
16865   u32 *action = va_arg (*args, u32 *);
16866   u8 *s = 0;
16867
16868   if (unformat (input, "%s", &s))
16869     {
16870       if (!strcmp ((char *) s, "no-action"))
16871         action[0] = 0;
16872       else if (!strcmp ((char *) s, "natively-forward"))
16873         action[0] = 1;
16874       else if (!strcmp ((char *) s, "send-map-request"))
16875         action[0] = 2;
16876       else if (!strcmp ((char *) s, "drop"))
16877         action[0] = 3;
16878       else
16879         {
16880           clib_warning ("invalid action: '%s'", s);
16881           action[0] = 3;
16882         }
16883     }
16884   else
16885     return 0;
16886
16887   vec_free (s);
16888   return 1;
16889 }
16890
16891 /**
16892  * Add/del remote mapping to/from ONE control plane
16893  *
16894  * @param vam vpp API test context
16895  * @return return code
16896  */
16897 static int
16898 api_one_add_del_remote_mapping (vat_main_t * vam)
16899 {
16900   unformat_input_t *input = vam->input;
16901   vl_api_one_add_del_remote_mapping_t *mp;
16902   u32 vni = 0;
16903   lisp_eid_vat_t _eid, *eid = &_eid;
16904   lisp_eid_vat_t _seid, *seid = &_seid;
16905   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16906   u32 action = ~0, p, w, data_len;
16907   ip4_address_t rloc4;
16908   ip6_address_t rloc6;
16909   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16910   int ret;
16911
16912   clib_memset (&rloc, 0, sizeof (rloc));
16913
16914   /* Parse args required to build the message */
16915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16916     {
16917       if (unformat (input, "del-all"))
16918         {
16919           del_all = 1;
16920         }
16921       else if (unformat (input, "del"))
16922         {
16923           is_add = 0;
16924         }
16925       else if (unformat (input, "add"))
16926         {
16927           is_add = 1;
16928         }
16929       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16930         {
16931           eid_set = 1;
16932         }
16933       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16934         {
16935           seid_set = 1;
16936         }
16937       else if (unformat (input, "vni %d", &vni))
16938         {
16939           ;
16940         }
16941       else if (unformat (input, "p %d w %d", &p, &w))
16942         {
16943           if (!curr_rloc)
16944             {
16945               errmsg ("No RLOC configured for setting priority/weight!");
16946               return -99;
16947             }
16948           curr_rloc->priority = p;
16949           curr_rloc->weight = w;
16950         }
16951       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16952         {
16953           rloc.is_ip4 = 1;
16954           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16955           vec_add1 (rlocs, rloc);
16956           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16957         }
16958       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16959         {
16960           rloc.is_ip4 = 0;
16961           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16962           vec_add1 (rlocs, rloc);
16963           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16964         }
16965       else if (unformat (input, "action %U",
16966                          unformat_negative_mapping_action, &action))
16967         {
16968           ;
16969         }
16970       else
16971         {
16972           clib_warning ("parse error '%U'", format_unformat_error, input);
16973           return -99;
16974         }
16975     }
16976
16977   if (0 == eid_set)
16978     {
16979       errmsg ("missing params!");
16980       return -99;
16981     }
16982
16983   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16984     {
16985       errmsg ("no action set for negative map-reply!");
16986       return -99;
16987     }
16988
16989   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16990
16991   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16992   mp->is_add = is_add;
16993   mp->vni = htonl (vni);
16994   mp->action = (u8) action;
16995   mp->is_src_dst = seid_set;
16996   mp->eid_len = eid->len;
16997   mp->seid_len = seid->len;
16998   mp->del_all = del_all;
16999   mp->eid_type = eid->type;
17000   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17001   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17002
17003   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17004   clib_memcpy (mp->rlocs, rlocs, data_len);
17005   vec_free (rlocs);
17006
17007   /* send it... */
17008   S (mp);
17009
17010   /* Wait for a reply... */
17011   W (ret);
17012   return ret;
17013 }
17014
17015 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17016
17017 /**
17018  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17019  * forwarding entries in data-plane accordingly.
17020  *
17021  * @param vam vpp API test context
17022  * @return return code
17023  */
17024 static int
17025 api_one_add_del_adjacency (vat_main_t * vam)
17026 {
17027   unformat_input_t *input = vam->input;
17028   vl_api_one_add_del_adjacency_t *mp;
17029   u32 vni = 0;
17030   ip4_address_t leid4, reid4;
17031   ip6_address_t leid6, reid6;
17032   u8 reid_mac[6] = { 0 };
17033   u8 leid_mac[6] = { 0 };
17034   u8 reid_type, leid_type;
17035   u32 leid_len = 0, reid_len = 0, len;
17036   u8 is_add = 1;
17037   int ret;
17038
17039   leid_type = reid_type = (u8) ~ 0;
17040
17041   /* Parse args required to build the message */
17042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17043     {
17044       if (unformat (input, "del"))
17045         {
17046           is_add = 0;
17047         }
17048       else if (unformat (input, "add"))
17049         {
17050           is_add = 1;
17051         }
17052       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17053                          &reid4, &len))
17054         {
17055           reid_type = 0;        /* ipv4 */
17056           reid_len = len;
17057         }
17058       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17059                          &reid6, &len))
17060         {
17061           reid_type = 1;        /* ipv6 */
17062           reid_len = len;
17063         }
17064       else if (unformat (input, "reid %U", unformat_ethernet_address,
17065                          reid_mac))
17066         {
17067           reid_type = 2;        /* mac */
17068         }
17069       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17070                          &leid4, &len))
17071         {
17072           leid_type = 0;        /* ipv4 */
17073           leid_len = len;
17074         }
17075       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17076                          &leid6, &len))
17077         {
17078           leid_type = 1;        /* ipv6 */
17079           leid_len = len;
17080         }
17081       else if (unformat (input, "leid %U", unformat_ethernet_address,
17082                          leid_mac))
17083         {
17084           leid_type = 2;        /* mac */
17085         }
17086       else if (unformat (input, "vni %d", &vni))
17087         {
17088           ;
17089         }
17090       else
17091         {
17092           errmsg ("parse error '%U'", format_unformat_error, input);
17093           return -99;
17094         }
17095     }
17096
17097   if ((u8) ~ 0 == reid_type)
17098     {
17099       errmsg ("missing params!");
17100       return -99;
17101     }
17102
17103   if (leid_type != reid_type)
17104     {
17105       errmsg ("remote and local EIDs are of different types!");
17106       return -99;
17107     }
17108
17109   M (ONE_ADD_DEL_ADJACENCY, mp);
17110   mp->is_add = is_add;
17111   mp->vni = htonl (vni);
17112   mp->leid_len = leid_len;
17113   mp->reid_len = reid_len;
17114   mp->eid_type = reid_type;
17115
17116   switch (mp->eid_type)
17117     {
17118     case 0:
17119       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17120       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17121       break;
17122     case 1:
17123       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17124       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17125       break;
17126     case 2:
17127       clib_memcpy (mp->leid, leid_mac, 6);
17128       clib_memcpy (mp->reid, reid_mac, 6);
17129       break;
17130     default:
17131       errmsg ("unknown EID type %d!", mp->eid_type);
17132       return 0;
17133     }
17134
17135   /* send it... */
17136   S (mp);
17137
17138   /* Wait for a reply... */
17139   W (ret);
17140   return ret;
17141 }
17142
17143 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17144
17145 uword
17146 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17147 {
17148   u32 *mode = va_arg (*args, u32 *);
17149
17150   if (unformat (input, "lisp"))
17151     *mode = 0;
17152   else if (unformat (input, "vxlan"))
17153     *mode = 1;
17154   else
17155     return 0;
17156
17157   return 1;
17158 }
17159
17160 static int
17161 api_gpe_get_encap_mode (vat_main_t * vam)
17162 {
17163   vl_api_gpe_get_encap_mode_t *mp;
17164   int ret;
17165
17166   /* Construct the API message */
17167   M (GPE_GET_ENCAP_MODE, mp);
17168
17169   /* send it... */
17170   S (mp);
17171
17172   /* Wait for a reply... */
17173   W (ret);
17174   return ret;
17175 }
17176
17177 static int
17178 api_gpe_set_encap_mode (vat_main_t * vam)
17179 {
17180   unformat_input_t *input = vam->input;
17181   vl_api_gpe_set_encap_mode_t *mp;
17182   int ret;
17183   u32 mode = 0;
17184
17185   /* Parse args required to build the message */
17186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17187     {
17188       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17189         ;
17190       else
17191         break;
17192     }
17193
17194   /* Construct the API message */
17195   M (GPE_SET_ENCAP_MODE, mp);
17196
17197   mp->mode = mode;
17198
17199   /* send it... */
17200   S (mp);
17201
17202   /* Wait for a reply... */
17203   W (ret);
17204   return ret;
17205 }
17206
17207 static int
17208 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17209 {
17210   unformat_input_t *input = vam->input;
17211   vl_api_gpe_add_del_iface_t *mp;
17212   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17213   u32 dp_table = 0, vni = 0;
17214   int ret;
17215
17216   /* Parse args required to build the message */
17217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17218     {
17219       if (unformat (input, "up"))
17220         {
17221           action_set = 1;
17222           is_add = 1;
17223         }
17224       else if (unformat (input, "down"))
17225         {
17226           action_set = 1;
17227           is_add = 0;
17228         }
17229       else if (unformat (input, "table_id %d", &dp_table))
17230         {
17231           dp_table_set = 1;
17232         }
17233       else if (unformat (input, "bd_id %d", &dp_table))
17234         {
17235           dp_table_set = 1;
17236           is_l2 = 1;
17237         }
17238       else if (unformat (input, "vni %d", &vni))
17239         {
17240           vni_set = 1;
17241         }
17242       else
17243         break;
17244     }
17245
17246   if (action_set == 0)
17247     {
17248       errmsg ("Action not set");
17249       return -99;
17250     }
17251   if (dp_table_set == 0 || vni_set == 0)
17252     {
17253       errmsg ("vni and dp_table must be set");
17254       return -99;
17255     }
17256
17257   /* Construct the API message */
17258   M (GPE_ADD_DEL_IFACE, mp);
17259
17260   mp->is_add = is_add;
17261   mp->dp_table = clib_host_to_net_u32 (dp_table);
17262   mp->is_l2 = is_l2;
17263   mp->vni = clib_host_to_net_u32 (vni);
17264
17265   /* send it... */
17266   S (mp);
17267
17268   /* Wait for a reply... */
17269   W (ret);
17270   return ret;
17271 }
17272
17273 static int
17274 api_one_map_register_fallback_threshold (vat_main_t * vam)
17275 {
17276   unformat_input_t *input = vam->input;
17277   vl_api_one_map_register_fallback_threshold_t *mp;
17278   u32 value = 0;
17279   u8 is_set = 0;
17280   int ret;
17281
17282   /* Parse args required to build the message */
17283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17284     {
17285       if (unformat (input, "%u", &value))
17286         is_set = 1;
17287       else
17288         {
17289           clib_warning ("parse error '%U'", format_unformat_error, input);
17290           return -99;
17291         }
17292     }
17293
17294   if (!is_set)
17295     {
17296       errmsg ("fallback threshold value is missing!");
17297       return -99;
17298     }
17299
17300   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17301   mp->value = clib_host_to_net_u32 (value);
17302
17303   /* send it... */
17304   S (mp);
17305
17306   /* Wait for a reply... */
17307   W (ret);
17308   return ret;
17309 }
17310
17311 static int
17312 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17313 {
17314   vl_api_show_one_map_register_fallback_threshold_t *mp;
17315   int ret;
17316
17317   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17318
17319   /* send it... */
17320   S (mp);
17321
17322   /* Wait for a reply... */
17323   W (ret);
17324   return ret;
17325 }
17326
17327 uword
17328 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17329 {
17330   u32 *proto = va_arg (*args, u32 *);
17331
17332   if (unformat (input, "udp"))
17333     *proto = 1;
17334   else if (unformat (input, "api"))
17335     *proto = 2;
17336   else
17337     return 0;
17338
17339   return 1;
17340 }
17341
17342 static int
17343 api_one_set_transport_protocol (vat_main_t * vam)
17344 {
17345   unformat_input_t *input = vam->input;
17346   vl_api_one_set_transport_protocol_t *mp;
17347   u8 is_set = 0;
17348   u32 protocol = 0;
17349   int ret;
17350
17351   /* Parse args required to build the message */
17352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17353     {
17354       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17355         is_set = 1;
17356       else
17357         {
17358           clib_warning ("parse error '%U'", format_unformat_error, input);
17359           return -99;
17360         }
17361     }
17362
17363   if (!is_set)
17364     {
17365       errmsg ("Transport protocol missing!");
17366       return -99;
17367     }
17368
17369   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17370   mp->protocol = (u8) protocol;
17371
17372   /* send it... */
17373   S (mp);
17374
17375   /* Wait for a reply... */
17376   W (ret);
17377   return ret;
17378 }
17379
17380 static int
17381 api_one_get_transport_protocol (vat_main_t * vam)
17382 {
17383   vl_api_one_get_transport_protocol_t *mp;
17384   int ret;
17385
17386   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17387
17388   /* send it... */
17389   S (mp);
17390
17391   /* Wait for a reply... */
17392   W (ret);
17393   return ret;
17394 }
17395
17396 static int
17397 api_one_map_register_set_ttl (vat_main_t * vam)
17398 {
17399   unformat_input_t *input = vam->input;
17400   vl_api_one_map_register_set_ttl_t *mp;
17401   u32 ttl = 0;
17402   u8 is_set = 0;
17403   int ret;
17404
17405   /* Parse args required to build the message */
17406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17407     {
17408       if (unformat (input, "%u", &ttl))
17409         is_set = 1;
17410       else
17411         {
17412           clib_warning ("parse error '%U'", format_unformat_error, input);
17413           return -99;
17414         }
17415     }
17416
17417   if (!is_set)
17418     {
17419       errmsg ("TTL value missing!");
17420       return -99;
17421     }
17422
17423   M (ONE_MAP_REGISTER_SET_TTL, mp);
17424   mp->ttl = clib_host_to_net_u32 (ttl);
17425
17426   /* send it... */
17427   S (mp);
17428
17429   /* Wait for a reply... */
17430   W (ret);
17431   return ret;
17432 }
17433
17434 static int
17435 api_show_one_map_register_ttl (vat_main_t * vam)
17436 {
17437   vl_api_show_one_map_register_ttl_t *mp;
17438   int ret;
17439
17440   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17441
17442   /* send it... */
17443   S (mp);
17444
17445   /* Wait for a reply... */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 /**
17451  * Add/del map request itr rlocs from ONE control plane and updates
17452  *
17453  * @param vam vpp API test context
17454  * @return return code
17455  */
17456 static int
17457 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17458 {
17459   unformat_input_t *input = vam->input;
17460   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17461   u8 *locator_set_name = 0;
17462   u8 locator_set_name_set = 0;
17463   u8 is_add = 1;
17464   int ret;
17465
17466   /* Parse args required to build the message */
17467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17468     {
17469       if (unformat (input, "del"))
17470         {
17471           is_add = 0;
17472         }
17473       else if (unformat (input, "%_%v%_", &locator_set_name))
17474         {
17475           locator_set_name_set = 1;
17476         }
17477       else
17478         {
17479           clib_warning ("parse error '%U'", format_unformat_error, input);
17480           return -99;
17481         }
17482     }
17483
17484   if (is_add && !locator_set_name_set)
17485     {
17486       errmsg ("itr-rloc is not set!");
17487       return -99;
17488     }
17489
17490   if (is_add && vec_len (locator_set_name) > 64)
17491     {
17492       errmsg ("itr-rloc locator-set name too long");
17493       vec_free (locator_set_name);
17494       return -99;
17495     }
17496
17497   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17498   mp->is_add = is_add;
17499   if (is_add)
17500     {
17501       clib_memcpy (mp->locator_set_name, locator_set_name,
17502                    vec_len (locator_set_name));
17503     }
17504   else
17505     {
17506       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17507     }
17508   vec_free (locator_set_name);
17509
17510   /* send it... */
17511   S (mp);
17512
17513   /* Wait for a reply... */
17514   W (ret);
17515   return ret;
17516 }
17517
17518 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17519
17520 static int
17521 api_one_locator_dump (vat_main_t * vam)
17522 {
17523   unformat_input_t *input = vam->input;
17524   vl_api_one_locator_dump_t *mp;
17525   vl_api_control_ping_t *mp_ping;
17526   u8 is_index_set = 0, is_name_set = 0;
17527   u8 *ls_name = 0;
17528   u32 ls_index = ~0;
17529   int ret;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "ls_name %_%v%_", &ls_name))
17535         {
17536           is_name_set = 1;
17537         }
17538       else if (unformat (input, "ls_index %d", &ls_index))
17539         {
17540           is_index_set = 1;
17541         }
17542       else
17543         {
17544           errmsg ("parse error '%U'", format_unformat_error, input);
17545           return -99;
17546         }
17547     }
17548
17549   if (!is_index_set && !is_name_set)
17550     {
17551       errmsg ("error: expected one of index or name!");
17552       return -99;
17553     }
17554
17555   if (is_index_set && is_name_set)
17556     {
17557       errmsg ("error: only one param expected!");
17558       return -99;
17559     }
17560
17561   if (vec_len (ls_name) > 62)
17562     {
17563       errmsg ("error: locator set name too long!");
17564       return -99;
17565     }
17566
17567   if (!vam->json_output)
17568     {
17569       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17570     }
17571
17572   M (ONE_LOCATOR_DUMP, mp);
17573   mp->is_index_set = is_index_set;
17574
17575   if (is_index_set)
17576     mp->ls_index = clib_host_to_net_u32 (ls_index);
17577   else
17578     {
17579       vec_add1 (ls_name, 0);
17580       strncpy ((char *) mp->ls_name, (char *) ls_name,
17581                sizeof (mp->ls_name) - 1);
17582     }
17583
17584   /* send it... */
17585   S (mp);
17586
17587   /* Use a control ping for synchronization */
17588   MPING (CONTROL_PING, mp_ping);
17589   S (mp_ping);
17590
17591   /* Wait for a reply... */
17592   W (ret);
17593   return ret;
17594 }
17595
17596 #define api_lisp_locator_dump api_one_locator_dump
17597
17598 static int
17599 api_one_locator_set_dump (vat_main_t * vam)
17600 {
17601   vl_api_one_locator_set_dump_t *mp;
17602   vl_api_control_ping_t *mp_ping;
17603   unformat_input_t *input = vam->input;
17604   u8 filter = 0;
17605   int ret;
17606
17607   /* Parse args required to build the message */
17608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17609     {
17610       if (unformat (input, "local"))
17611         {
17612           filter = 1;
17613         }
17614       else if (unformat (input, "remote"))
17615         {
17616           filter = 2;
17617         }
17618       else
17619         {
17620           errmsg ("parse error '%U'", format_unformat_error, input);
17621           return -99;
17622         }
17623     }
17624
17625   if (!vam->json_output)
17626     {
17627       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17628     }
17629
17630   M (ONE_LOCATOR_SET_DUMP, mp);
17631
17632   mp->filter = filter;
17633
17634   /* send it... */
17635   S (mp);
17636
17637   /* Use a control ping for synchronization */
17638   MPING (CONTROL_PING, mp_ping);
17639   S (mp_ping);
17640
17641   /* Wait for a reply... */
17642   W (ret);
17643   return ret;
17644 }
17645
17646 #define api_lisp_locator_set_dump api_one_locator_set_dump
17647
17648 static int
17649 api_one_eid_table_map_dump (vat_main_t * vam)
17650 {
17651   u8 is_l2 = 0;
17652   u8 mode_set = 0;
17653   unformat_input_t *input = vam->input;
17654   vl_api_one_eid_table_map_dump_t *mp;
17655   vl_api_control_ping_t *mp_ping;
17656   int ret;
17657
17658   /* Parse args required to build the message */
17659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17660     {
17661       if (unformat (input, "l2"))
17662         {
17663           is_l2 = 1;
17664           mode_set = 1;
17665         }
17666       else if (unformat (input, "l3"))
17667         {
17668           is_l2 = 0;
17669           mode_set = 1;
17670         }
17671       else
17672         {
17673           errmsg ("parse error '%U'", format_unformat_error, input);
17674           return -99;
17675         }
17676     }
17677
17678   if (!mode_set)
17679     {
17680       errmsg ("expected one of 'l2' or 'l3' parameter!");
17681       return -99;
17682     }
17683
17684   if (!vam->json_output)
17685     {
17686       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17687     }
17688
17689   M (ONE_EID_TABLE_MAP_DUMP, mp);
17690   mp->is_l2 = is_l2;
17691
17692   /* send it... */
17693   S (mp);
17694
17695   /* Use a control ping for synchronization */
17696   MPING (CONTROL_PING, mp_ping);
17697   S (mp_ping);
17698
17699   /* Wait for a reply... */
17700   W (ret);
17701   return ret;
17702 }
17703
17704 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17705
17706 static int
17707 api_one_eid_table_vni_dump (vat_main_t * vam)
17708 {
17709   vl_api_one_eid_table_vni_dump_t *mp;
17710   vl_api_control_ping_t *mp_ping;
17711   int ret;
17712
17713   if (!vam->json_output)
17714     {
17715       print (vam->ofp, "VNI");
17716     }
17717
17718   M (ONE_EID_TABLE_VNI_DUMP, mp);
17719
17720   /* send it... */
17721   S (mp);
17722
17723   /* Use a control ping for synchronization */
17724   MPING (CONTROL_PING, mp_ping);
17725   S (mp_ping);
17726
17727   /* Wait for a reply... */
17728   W (ret);
17729   return ret;
17730 }
17731
17732 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17733
17734 static int
17735 api_one_eid_table_dump (vat_main_t * vam)
17736 {
17737   unformat_input_t *i = vam->input;
17738   vl_api_one_eid_table_dump_t *mp;
17739   vl_api_control_ping_t *mp_ping;
17740   struct in_addr ip4;
17741   struct in6_addr ip6;
17742   u8 mac[6];
17743   u8 eid_type = ~0, eid_set = 0;
17744   u32 prefix_length = ~0, t, vni = 0;
17745   u8 filter = 0;
17746   int ret;
17747   lisp_nsh_api_t nsh;
17748
17749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17750     {
17751       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17752         {
17753           eid_set = 1;
17754           eid_type = 0;
17755           prefix_length = t;
17756         }
17757       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17758         {
17759           eid_set = 1;
17760           eid_type = 1;
17761           prefix_length = t;
17762         }
17763       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17764         {
17765           eid_set = 1;
17766           eid_type = 2;
17767         }
17768       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17769         {
17770           eid_set = 1;
17771           eid_type = 3;
17772         }
17773       else if (unformat (i, "vni %d", &t))
17774         {
17775           vni = t;
17776         }
17777       else if (unformat (i, "local"))
17778         {
17779           filter = 1;
17780         }
17781       else if (unformat (i, "remote"))
17782         {
17783           filter = 2;
17784         }
17785       else
17786         {
17787           errmsg ("parse error '%U'", format_unformat_error, i);
17788           return -99;
17789         }
17790     }
17791
17792   if (!vam->json_output)
17793     {
17794       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17795              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17796     }
17797
17798   M (ONE_EID_TABLE_DUMP, mp);
17799
17800   mp->filter = filter;
17801   if (eid_set)
17802     {
17803       mp->eid_set = 1;
17804       mp->vni = htonl (vni);
17805       mp->eid_type = eid_type;
17806       switch (eid_type)
17807         {
17808         case 0:
17809           mp->prefix_length = prefix_length;
17810           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17811           break;
17812         case 1:
17813           mp->prefix_length = prefix_length;
17814           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17815           break;
17816         case 2:
17817           clib_memcpy (mp->eid, mac, sizeof (mac));
17818           break;
17819         case 3:
17820           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17821           break;
17822         default:
17823           errmsg ("unknown EID type %d!", eid_type);
17824           return -99;
17825         }
17826     }
17827
17828   /* send it... */
17829   S (mp);
17830
17831   /* Use a control ping for synchronization */
17832   MPING (CONTROL_PING, mp_ping);
17833   S (mp_ping);
17834
17835   /* Wait for a reply... */
17836   W (ret);
17837   return ret;
17838 }
17839
17840 #define api_lisp_eid_table_dump api_one_eid_table_dump
17841
17842 static int
17843 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17844 {
17845   unformat_input_t *i = vam->input;
17846   vl_api_gpe_fwd_entries_get_t *mp;
17847   u8 vni_set = 0;
17848   u32 vni = ~0;
17849   int ret;
17850
17851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17852     {
17853       if (unformat (i, "vni %d", &vni))
17854         {
17855           vni_set = 1;
17856         }
17857       else
17858         {
17859           errmsg ("parse error '%U'", format_unformat_error, i);
17860           return -99;
17861         }
17862     }
17863
17864   if (!vni_set)
17865     {
17866       errmsg ("vni not set!");
17867       return -99;
17868     }
17869
17870   if (!vam->json_output)
17871     {
17872       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17873              "leid", "reid");
17874     }
17875
17876   M (GPE_FWD_ENTRIES_GET, mp);
17877   mp->vni = clib_host_to_net_u32 (vni);
17878
17879   /* send it... */
17880   S (mp);
17881
17882   /* Wait for a reply... */
17883   W (ret);
17884   return ret;
17885 }
17886
17887 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17888 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17889 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17890 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17891 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17892 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17893 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17894 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17895
17896 static int
17897 api_one_adjacencies_get (vat_main_t * vam)
17898 {
17899   unformat_input_t *i = vam->input;
17900   vl_api_one_adjacencies_get_t *mp;
17901   u8 vni_set = 0;
17902   u32 vni = ~0;
17903   int ret;
17904
17905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17906     {
17907       if (unformat (i, "vni %d", &vni))
17908         {
17909           vni_set = 1;
17910         }
17911       else
17912         {
17913           errmsg ("parse error '%U'", format_unformat_error, i);
17914           return -99;
17915         }
17916     }
17917
17918   if (!vni_set)
17919     {
17920       errmsg ("vni not set!");
17921       return -99;
17922     }
17923
17924   if (!vam->json_output)
17925     {
17926       print (vam->ofp, "%s %40s", "leid", "reid");
17927     }
17928
17929   M (ONE_ADJACENCIES_GET, mp);
17930   mp->vni = clib_host_to_net_u32 (vni);
17931
17932   /* send it... */
17933   S (mp);
17934
17935   /* Wait for a reply... */
17936   W (ret);
17937   return ret;
17938 }
17939
17940 #define api_lisp_adjacencies_get api_one_adjacencies_get
17941
17942 static int
17943 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17944 {
17945   unformat_input_t *i = vam->input;
17946   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17947   int ret;
17948   u8 ip_family_set = 0, is_ip4 = 1;
17949
17950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17951     {
17952       if (unformat (i, "ip4"))
17953         {
17954           ip_family_set = 1;
17955           is_ip4 = 1;
17956         }
17957       else if (unformat (i, "ip6"))
17958         {
17959           ip_family_set = 1;
17960           is_ip4 = 0;
17961         }
17962       else
17963         {
17964           errmsg ("parse error '%U'", format_unformat_error, i);
17965           return -99;
17966         }
17967     }
17968
17969   if (!ip_family_set)
17970     {
17971       errmsg ("ip family not set!");
17972       return -99;
17973     }
17974
17975   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17976   mp->is_ip4 = is_ip4;
17977
17978   /* send it... */
17979   S (mp);
17980
17981   /* Wait for a reply... */
17982   W (ret);
17983   return ret;
17984 }
17985
17986 static int
17987 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17988 {
17989   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17990   int ret;
17991
17992   if (!vam->json_output)
17993     {
17994       print (vam->ofp, "VNIs");
17995     }
17996
17997   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17998
17999   /* send it... */
18000   S (mp);
18001
18002   /* Wait for a reply... */
18003   W (ret);
18004   return ret;
18005 }
18006
18007 static int
18008 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18009 {
18010   unformat_input_t *i = vam->input;
18011   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18012   int ret = 0;
18013   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18014   struct in_addr ip4;
18015   struct in6_addr ip6;
18016   u32 table_id = 0, nh_sw_if_index = ~0;
18017
18018   clib_memset (&ip4, 0, sizeof (ip4));
18019   clib_memset (&ip6, 0, sizeof (ip6));
18020
18021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18022     {
18023       if (unformat (i, "del"))
18024         is_add = 0;
18025       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18026                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18027         {
18028           ip_set = 1;
18029           is_ip4 = 1;
18030         }
18031       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18032                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18033         {
18034           ip_set = 1;
18035           is_ip4 = 0;
18036         }
18037       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18038         {
18039           ip_set = 1;
18040           is_ip4 = 1;
18041           nh_sw_if_index = ~0;
18042         }
18043       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18044         {
18045           ip_set = 1;
18046           is_ip4 = 0;
18047           nh_sw_if_index = ~0;
18048         }
18049       else if (unformat (i, "table %d", &table_id))
18050         ;
18051       else
18052         {
18053           errmsg ("parse error '%U'", format_unformat_error, i);
18054           return -99;
18055         }
18056     }
18057
18058   if (!ip_set)
18059     {
18060       errmsg ("nh addr not set!");
18061       return -99;
18062     }
18063
18064   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18065   mp->is_add = is_add;
18066   mp->table_id = clib_host_to_net_u32 (table_id);
18067   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18068   mp->is_ip4 = is_ip4;
18069   if (is_ip4)
18070     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18071   else
18072     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18073
18074   /* send it... */
18075   S (mp);
18076
18077   /* Wait for a reply... */
18078   W (ret);
18079   return ret;
18080 }
18081
18082 static int
18083 api_one_map_server_dump (vat_main_t * vam)
18084 {
18085   vl_api_one_map_server_dump_t *mp;
18086   vl_api_control_ping_t *mp_ping;
18087   int ret;
18088
18089   if (!vam->json_output)
18090     {
18091       print (vam->ofp, "%=20s", "Map server");
18092     }
18093
18094   M (ONE_MAP_SERVER_DUMP, mp);
18095   /* send it... */
18096   S (mp);
18097
18098   /* Use a control ping for synchronization */
18099   MPING (CONTROL_PING, mp_ping);
18100   S (mp_ping);
18101
18102   /* Wait for a reply... */
18103   W (ret);
18104   return ret;
18105 }
18106
18107 #define api_lisp_map_server_dump api_one_map_server_dump
18108
18109 static int
18110 api_one_map_resolver_dump (vat_main_t * vam)
18111 {
18112   vl_api_one_map_resolver_dump_t *mp;
18113   vl_api_control_ping_t *mp_ping;
18114   int ret;
18115
18116   if (!vam->json_output)
18117     {
18118       print (vam->ofp, "%=20s", "Map resolver");
18119     }
18120
18121   M (ONE_MAP_RESOLVER_DUMP, mp);
18122   /* send it... */
18123   S (mp);
18124
18125   /* Use a control ping for synchronization */
18126   MPING (CONTROL_PING, mp_ping);
18127   S (mp_ping);
18128
18129   /* Wait for a reply... */
18130   W (ret);
18131   return ret;
18132 }
18133
18134 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18135
18136 static int
18137 api_one_stats_flush (vat_main_t * vam)
18138 {
18139   vl_api_one_stats_flush_t *mp;
18140   int ret = 0;
18141
18142   M (ONE_STATS_FLUSH, mp);
18143   S (mp);
18144   W (ret);
18145   return ret;
18146 }
18147
18148 static int
18149 api_one_stats_dump (vat_main_t * vam)
18150 {
18151   vl_api_one_stats_dump_t *mp;
18152   vl_api_control_ping_t *mp_ping;
18153   int ret;
18154
18155   M (ONE_STATS_DUMP, mp);
18156   /* send it... */
18157   S (mp);
18158
18159   /* Use a control ping for synchronization */
18160   MPING (CONTROL_PING, mp_ping);
18161   S (mp_ping);
18162
18163   /* Wait for a reply... */
18164   W (ret);
18165   return ret;
18166 }
18167
18168 static int
18169 api_show_one_status (vat_main_t * vam)
18170 {
18171   vl_api_show_one_status_t *mp;
18172   int ret;
18173
18174   if (!vam->json_output)
18175     {
18176       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18177     }
18178
18179   M (SHOW_ONE_STATUS, mp);
18180   /* send it... */
18181   S (mp);
18182   /* Wait for a reply... */
18183   W (ret);
18184   return ret;
18185 }
18186
18187 #define api_show_lisp_status api_show_one_status
18188
18189 static int
18190 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18191 {
18192   vl_api_gpe_fwd_entry_path_dump_t *mp;
18193   vl_api_control_ping_t *mp_ping;
18194   unformat_input_t *i = vam->input;
18195   u32 fwd_entry_index = ~0;
18196   int ret;
18197
18198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18199     {
18200       if (unformat (i, "index %d", &fwd_entry_index))
18201         ;
18202       else
18203         break;
18204     }
18205
18206   if (~0 == fwd_entry_index)
18207     {
18208       errmsg ("no index specified!");
18209       return -99;
18210     }
18211
18212   if (!vam->json_output)
18213     {
18214       print (vam->ofp, "first line");
18215     }
18216
18217   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18218
18219   /* send it... */
18220   S (mp);
18221   /* Use a control ping for synchronization */
18222   MPING (CONTROL_PING, mp_ping);
18223   S (mp_ping);
18224
18225   /* Wait for a reply... */
18226   W (ret);
18227   return ret;
18228 }
18229
18230 static int
18231 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18232 {
18233   vl_api_one_get_map_request_itr_rlocs_t *mp;
18234   int ret;
18235
18236   if (!vam->json_output)
18237     {
18238       print (vam->ofp, "%=20s", "itr-rlocs:");
18239     }
18240
18241   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18242   /* send it... */
18243   S (mp);
18244   /* Wait for a reply... */
18245   W (ret);
18246   return ret;
18247 }
18248
18249 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18250
18251 static int
18252 api_af_packet_create (vat_main_t * vam)
18253 {
18254   unformat_input_t *i = vam->input;
18255   vl_api_af_packet_create_t *mp;
18256   u8 *host_if_name = 0;
18257   u8 hw_addr[6];
18258   u8 random_hw_addr = 1;
18259   int ret;
18260
18261   clib_memset (hw_addr, 0, sizeof (hw_addr));
18262
18263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18264     {
18265       if (unformat (i, "name %s", &host_if_name))
18266         vec_add1 (host_if_name, 0);
18267       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18268         random_hw_addr = 0;
18269       else
18270         break;
18271     }
18272
18273   if (!vec_len (host_if_name))
18274     {
18275       errmsg ("host-interface name must be specified");
18276       return -99;
18277     }
18278
18279   if (vec_len (host_if_name) > 64)
18280     {
18281       errmsg ("host-interface name too long");
18282       return -99;
18283     }
18284
18285   M (AF_PACKET_CREATE, mp);
18286
18287   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18288   clib_memcpy (mp->hw_addr, hw_addr, 6);
18289   mp->use_random_hw_addr = random_hw_addr;
18290   vec_free (host_if_name);
18291
18292   S (mp);
18293
18294   /* *INDENT-OFF* */
18295   W2 (ret,
18296       ({
18297         if (ret == 0)
18298           fprintf (vam->ofp ? vam->ofp : stderr,
18299                    " new sw_if_index = %d\n", vam->sw_if_index);
18300       }));
18301   /* *INDENT-ON* */
18302   return ret;
18303 }
18304
18305 static int
18306 api_af_packet_delete (vat_main_t * vam)
18307 {
18308   unformat_input_t *i = vam->input;
18309   vl_api_af_packet_delete_t *mp;
18310   u8 *host_if_name = 0;
18311   int ret;
18312
18313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18314     {
18315       if (unformat (i, "name %s", &host_if_name))
18316         vec_add1 (host_if_name, 0);
18317       else
18318         break;
18319     }
18320
18321   if (!vec_len (host_if_name))
18322     {
18323       errmsg ("host-interface name must be specified");
18324       return -99;
18325     }
18326
18327   if (vec_len (host_if_name) > 64)
18328     {
18329       errmsg ("host-interface name too long");
18330       return -99;
18331     }
18332
18333   M (AF_PACKET_DELETE, mp);
18334
18335   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18336   vec_free (host_if_name);
18337
18338   S (mp);
18339   W (ret);
18340   return ret;
18341 }
18342
18343 static void vl_api_af_packet_details_t_handler
18344   (vl_api_af_packet_details_t * mp)
18345 {
18346   vat_main_t *vam = &vat_main;
18347
18348   print (vam->ofp, "%-16s %d",
18349          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18350 }
18351
18352 static void vl_api_af_packet_details_t_handler_json
18353   (vl_api_af_packet_details_t * mp)
18354 {
18355   vat_main_t *vam = &vat_main;
18356   vat_json_node_t *node = NULL;
18357
18358   if (VAT_JSON_ARRAY != vam->json_tree.type)
18359     {
18360       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18361       vat_json_init_array (&vam->json_tree);
18362     }
18363   node = vat_json_array_add (&vam->json_tree);
18364
18365   vat_json_init_object (node);
18366   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18367   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18368 }
18369
18370 static int
18371 api_af_packet_dump (vat_main_t * vam)
18372 {
18373   vl_api_af_packet_dump_t *mp;
18374   vl_api_control_ping_t *mp_ping;
18375   int ret;
18376
18377   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18378   /* Get list of tap interfaces */
18379   M (AF_PACKET_DUMP, mp);
18380   S (mp);
18381
18382   /* Use a control ping for synchronization */
18383   MPING (CONTROL_PING, mp_ping);
18384   S (mp_ping);
18385
18386   W (ret);
18387   return ret;
18388 }
18389
18390 static int
18391 api_policer_add_del (vat_main_t * vam)
18392 {
18393   unformat_input_t *i = vam->input;
18394   vl_api_policer_add_del_t *mp;
18395   u8 is_add = 1;
18396   u8 *name = 0;
18397   u32 cir = 0;
18398   u32 eir = 0;
18399   u64 cb = 0;
18400   u64 eb = 0;
18401   u8 rate_type = 0;
18402   u8 round_type = 0;
18403   u8 type = 0;
18404   u8 color_aware = 0;
18405   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18406   int ret;
18407
18408   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18409   conform_action.dscp = 0;
18410   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18411   exceed_action.dscp = 0;
18412   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18413   violate_action.dscp = 0;
18414
18415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18416     {
18417       if (unformat (i, "del"))
18418         is_add = 0;
18419       else if (unformat (i, "name %s", &name))
18420         vec_add1 (name, 0);
18421       else if (unformat (i, "cir %u", &cir))
18422         ;
18423       else if (unformat (i, "eir %u", &eir))
18424         ;
18425       else if (unformat (i, "cb %u", &cb))
18426         ;
18427       else if (unformat (i, "eb %u", &eb))
18428         ;
18429       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18430                          &rate_type))
18431         ;
18432       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18433                          &round_type))
18434         ;
18435       else if (unformat (i, "type %U", unformat_policer_type, &type))
18436         ;
18437       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18438                          &conform_action))
18439         ;
18440       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18441                          &exceed_action))
18442         ;
18443       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18444                          &violate_action))
18445         ;
18446       else if (unformat (i, "color-aware"))
18447         color_aware = 1;
18448       else
18449         break;
18450     }
18451
18452   if (!vec_len (name))
18453     {
18454       errmsg ("policer name must be specified");
18455       return -99;
18456     }
18457
18458   if (vec_len (name) > 64)
18459     {
18460       errmsg ("policer name too long");
18461       return -99;
18462     }
18463
18464   M (POLICER_ADD_DEL, mp);
18465
18466   clib_memcpy (mp->name, name, vec_len (name));
18467   vec_free (name);
18468   mp->is_add = is_add;
18469   mp->cir = ntohl (cir);
18470   mp->eir = ntohl (eir);
18471   mp->cb = clib_net_to_host_u64 (cb);
18472   mp->eb = clib_net_to_host_u64 (eb);
18473   mp->rate_type = rate_type;
18474   mp->round_type = round_type;
18475   mp->type = type;
18476   mp->conform_action_type = conform_action.action_type;
18477   mp->conform_dscp = conform_action.dscp;
18478   mp->exceed_action_type = exceed_action.action_type;
18479   mp->exceed_dscp = exceed_action.dscp;
18480   mp->violate_action_type = violate_action.action_type;
18481   mp->violate_dscp = violate_action.dscp;
18482   mp->color_aware = color_aware;
18483
18484   S (mp);
18485   W (ret);
18486   return ret;
18487 }
18488
18489 static int
18490 api_policer_dump (vat_main_t * vam)
18491 {
18492   unformat_input_t *i = vam->input;
18493   vl_api_policer_dump_t *mp;
18494   vl_api_control_ping_t *mp_ping;
18495   u8 *match_name = 0;
18496   u8 match_name_valid = 0;
18497   int ret;
18498
18499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (i, "name %s", &match_name))
18502         {
18503           vec_add1 (match_name, 0);
18504           match_name_valid = 1;
18505         }
18506       else
18507         break;
18508     }
18509
18510   M (POLICER_DUMP, mp);
18511   mp->match_name_valid = match_name_valid;
18512   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18513   vec_free (match_name);
18514   /* send it... */
18515   S (mp);
18516
18517   /* Use a control ping for synchronization */
18518   MPING (CONTROL_PING, mp_ping);
18519   S (mp_ping);
18520
18521   /* Wait for a reply... */
18522   W (ret);
18523   return ret;
18524 }
18525
18526 static int
18527 api_policer_classify_set_interface (vat_main_t * vam)
18528 {
18529   unformat_input_t *i = vam->input;
18530   vl_api_policer_classify_set_interface_t *mp;
18531   u32 sw_if_index;
18532   int sw_if_index_set;
18533   u32 ip4_table_index = ~0;
18534   u32 ip6_table_index = ~0;
18535   u32 l2_table_index = ~0;
18536   u8 is_add = 1;
18537   int ret;
18538
18539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18540     {
18541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18542         sw_if_index_set = 1;
18543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18544         sw_if_index_set = 1;
18545       else if (unformat (i, "del"))
18546         is_add = 0;
18547       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18548         ;
18549       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18550         ;
18551       else if (unformat (i, "l2-table %d", &l2_table_index))
18552         ;
18553       else
18554         {
18555           clib_warning ("parse error '%U'", format_unformat_error, i);
18556           return -99;
18557         }
18558     }
18559
18560   if (sw_if_index_set == 0)
18561     {
18562       errmsg ("missing interface name or sw_if_index");
18563       return -99;
18564     }
18565
18566   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18567
18568   mp->sw_if_index = ntohl (sw_if_index);
18569   mp->ip4_table_index = ntohl (ip4_table_index);
18570   mp->ip6_table_index = ntohl (ip6_table_index);
18571   mp->l2_table_index = ntohl (l2_table_index);
18572   mp->is_add = is_add;
18573
18574   S (mp);
18575   W (ret);
18576   return ret;
18577 }
18578
18579 static int
18580 api_policer_classify_dump (vat_main_t * vam)
18581 {
18582   unformat_input_t *i = vam->input;
18583   vl_api_policer_classify_dump_t *mp;
18584   vl_api_control_ping_t *mp_ping;
18585   u8 type = POLICER_CLASSIFY_N_TABLES;
18586   int ret;
18587
18588   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18589     ;
18590   else
18591     {
18592       errmsg ("classify table type must be specified");
18593       return -99;
18594     }
18595
18596   if (!vam->json_output)
18597     {
18598       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18599     }
18600
18601   M (POLICER_CLASSIFY_DUMP, mp);
18602   mp->type = type;
18603   /* send it... */
18604   S (mp);
18605
18606   /* Use a control ping for synchronization */
18607   MPING (CONTROL_PING, mp_ping);
18608   S (mp_ping);
18609
18610   /* Wait for a reply... */
18611   W (ret);
18612   return ret;
18613 }
18614
18615 static int
18616 api_netmap_create (vat_main_t * vam)
18617 {
18618   unformat_input_t *i = vam->input;
18619   vl_api_netmap_create_t *mp;
18620   u8 *if_name = 0;
18621   u8 hw_addr[6];
18622   u8 random_hw_addr = 1;
18623   u8 is_pipe = 0;
18624   u8 is_master = 0;
18625   int ret;
18626
18627   clib_memset (hw_addr, 0, sizeof (hw_addr));
18628
18629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18630     {
18631       if (unformat (i, "name %s", &if_name))
18632         vec_add1 (if_name, 0);
18633       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18634         random_hw_addr = 0;
18635       else if (unformat (i, "pipe"))
18636         is_pipe = 1;
18637       else if (unformat (i, "master"))
18638         is_master = 1;
18639       else if (unformat (i, "slave"))
18640         is_master = 0;
18641       else
18642         break;
18643     }
18644
18645   if (!vec_len (if_name))
18646     {
18647       errmsg ("interface name must be specified");
18648       return -99;
18649     }
18650
18651   if (vec_len (if_name) > 64)
18652     {
18653       errmsg ("interface name too long");
18654       return -99;
18655     }
18656
18657   M (NETMAP_CREATE, mp);
18658
18659   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18660   clib_memcpy (mp->hw_addr, hw_addr, 6);
18661   mp->use_random_hw_addr = random_hw_addr;
18662   mp->is_pipe = is_pipe;
18663   mp->is_master = is_master;
18664   vec_free (if_name);
18665
18666   S (mp);
18667   W (ret);
18668   return ret;
18669 }
18670
18671 static int
18672 api_netmap_delete (vat_main_t * vam)
18673 {
18674   unformat_input_t *i = vam->input;
18675   vl_api_netmap_delete_t *mp;
18676   u8 *if_name = 0;
18677   int ret;
18678
18679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18680     {
18681       if (unformat (i, "name %s", &if_name))
18682         vec_add1 (if_name, 0);
18683       else
18684         break;
18685     }
18686
18687   if (!vec_len (if_name))
18688     {
18689       errmsg ("interface name must be specified");
18690       return -99;
18691     }
18692
18693   if (vec_len (if_name) > 64)
18694     {
18695       errmsg ("interface name too long");
18696       return -99;
18697     }
18698
18699   M (NETMAP_DELETE, mp);
18700
18701   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18702   vec_free (if_name);
18703
18704   S (mp);
18705   W (ret);
18706   return ret;
18707 }
18708
18709 static u8 *
18710 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18711 {
18712   vl_api_fib_path_nh_proto_t proto =
18713     va_arg (*args, vl_api_fib_path_nh_proto_t);
18714
18715   switch (proto)
18716     {
18717     case FIB_API_PATH_NH_PROTO_IP4:
18718       s = format (s, "ip4");
18719       break;
18720     case FIB_API_PATH_NH_PROTO_IP6:
18721       s = format (s, "ip6");
18722       break;
18723     case FIB_API_PATH_NH_PROTO_MPLS:
18724       s = format (s, "mpls");
18725       break;
18726     case FIB_API_PATH_NH_PROTO_BIER:
18727       s = format (s, "bier");
18728       break;
18729     case FIB_API_PATH_NH_PROTO_ETHERNET:
18730       s = format (s, "ethernet");
18731       break;
18732     }
18733
18734   return (s);
18735 }
18736
18737 static u8 *
18738 format_vl_api_ip_address_union (u8 * s, va_list * args)
18739 {
18740   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18741   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18742
18743   switch (af)
18744     {
18745     case ADDRESS_IP4:
18746       s = format (s, "%U", format_ip4_address, u->ip4);
18747       break;
18748     case ADDRESS_IP6:
18749       s = format (s, "%U", format_ip6_address, u->ip6);
18750       break;
18751     }
18752   return (s);
18753 }
18754
18755 static u8 *
18756 format_vl_api_fib_path_type (u8 * s, va_list * args)
18757 {
18758   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18759
18760   switch (t)
18761     {
18762     case FIB_API_PATH_TYPE_NORMAL:
18763       s = format (s, "normal");
18764       break;
18765     case FIB_API_PATH_TYPE_LOCAL:
18766       s = format (s, "local");
18767       break;
18768     case FIB_API_PATH_TYPE_DROP:
18769       s = format (s, "drop");
18770       break;
18771     case FIB_API_PATH_TYPE_UDP_ENCAP:
18772       s = format (s, "udp-encap");
18773       break;
18774     case FIB_API_PATH_TYPE_BIER_IMP:
18775       s = format (s, "bier-imp");
18776       break;
18777     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18778       s = format (s, "unreach");
18779       break;
18780     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18781       s = format (s, "prohibit");
18782       break;
18783     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18784       s = format (s, "src-lookup");
18785       break;
18786     case FIB_API_PATH_TYPE_DVR:
18787       s = format (s, "dvr");
18788       break;
18789     case FIB_API_PATH_TYPE_INTERFACE_RX:
18790       s = format (s, "interface-rx");
18791       break;
18792     case FIB_API_PATH_TYPE_CLASSIFY:
18793       s = format (s, "classify");
18794       break;
18795     }
18796
18797   return (s);
18798 }
18799
18800 static void
18801 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18802 {
18803   print (vam->ofp,
18804          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18805          ntohl (fp->weight), ntohl (fp->sw_if_index),
18806          format_vl_api_fib_path_type, fp->type,
18807          format_fib_api_path_nh_proto, fp->proto,
18808          format_vl_api_ip_address_union, &fp->nh.address);
18809 }
18810
18811 static void
18812 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18813                                  vl_api_fib_path_t * fp)
18814 {
18815   struct in_addr ip4;
18816   struct in6_addr ip6;
18817
18818   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18819   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18820   vat_json_object_add_uint (node, "type", fp->type);
18821   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18822   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18823     {
18824       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18825       vat_json_object_add_ip4 (node, "next_hop", ip4);
18826     }
18827   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18828     {
18829       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18830       vat_json_object_add_ip6 (node, "next_hop", ip6);
18831     }
18832 }
18833
18834 static void
18835 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18836 {
18837   vat_main_t *vam = &vat_main;
18838   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18839   vl_api_fib_path_t *fp;
18840   i32 i;
18841
18842   print (vam->ofp, "sw_if_index %d via:",
18843          ntohl (mp->mt_tunnel.mt_sw_if_index));
18844   fp = mp->mt_tunnel.mt_paths;
18845   for (i = 0; i < count; i++)
18846     {
18847       vl_api_fib_path_print (vam, fp);
18848       fp++;
18849     }
18850
18851   print (vam->ofp, "");
18852 }
18853
18854 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18855 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18856
18857 static void
18858 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18859 {
18860   vat_main_t *vam = &vat_main;
18861   vat_json_node_t *node = NULL;
18862   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18863   vl_api_fib_path_t *fp;
18864   i32 i;
18865
18866   if (VAT_JSON_ARRAY != vam->json_tree.type)
18867     {
18868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18869       vat_json_init_array (&vam->json_tree);
18870     }
18871   node = vat_json_array_add (&vam->json_tree);
18872
18873   vat_json_init_object (node);
18874   vat_json_object_add_uint (node, "sw_if_index",
18875                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18876
18877   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18878
18879   fp = mp->mt_tunnel.mt_paths;
18880   for (i = 0; i < count; i++)
18881     {
18882       vl_api_mpls_fib_path_json_print (node, fp);
18883       fp++;
18884     }
18885 }
18886
18887 static int
18888 api_mpls_tunnel_dump (vat_main_t * vam)
18889 {
18890   vl_api_mpls_tunnel_dump_t *mp;
18891   vl_api_control_ping_t *mp_ping;
18892   int ret;
18893
18894   M (MPLS_TUNNEL_DUMP, mp);
18895
18896   S (mp);
18897
18898   /* Use a control ping for synchronization */
18899   MPING (CONTROL_PING, mp_ping);
18900   S (mp_ping);
18901
18902   W (ret);
18903   return ret;
18904 }
18905
18906 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18907 #define vl_api_mpls_table_details_t_print vl_noop_handler
18908
18909
18910 static void
18911 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18912 {
18913   vat_main_t *vam = &vat_main;
18914
18915   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18916 }
18917
18918 static void vl_api_mpls_table_details_t_handler_json
18919   (vl_api_mpls_table_details_t * mp)
18920 {
18921   vat_main_t *vam = &vat_main;
18922   vat_json_node_t *node = NULL;
18923
18924   if (VAT_JSON_ARRAY != vam->json_tree.type)
18925     {
18926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18927       vat_json_init_array (&vam->json_tree);
18928     }
18929   node = vat_json_array_add (&vam->json_tree);
18930
18931   vat_json_init_object (node);
18932   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18933 }
18934
18935 static int
18936 api_mpls_table_dump (vat_main_t * vam)
18937 {
18938   vl_api_mpls_table_dump_t *mp;
18939   vl_api_control_ping_t *mp_ping;
18940   int ret;
18941
18942   M (MPLS_TABLE_DUMP, mp);
18943   S (mp);
18944
18945   /* Use a control ping for synchronization */
18946   MPING (CONTROL_PING, mp_ping);
18947   S (mp_ping);
18948
18949   W (ret);
18950   return ret;
18951 }
18952
18953 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18954 #define vl_api_mpls_route_details_t_print vl_noop_handler
18955
18956 static void
18957 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18958 {
18959   vat_main_t *vam = &vat_main;
18960   int count = ntohl (mp->mr_route.mr_n_paths);
18961   vl_api_fib_path_t *fp;
18962   int i;
18963
18964   print (vam->ofp,
18965          "table-id %d, label %u, ess_bit %u",
18966          ntohl (mp->mr_route.mr_table_id),
18967          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18968   fp = mp->mr_route.mr_paths;
18969   for (i = 0; i < count; i++)
18970     {
18971       vl_api_fib_path_print (vam, fp);
18972       fp++;
18973     }
18974 }
18975
18976 static void vl_api_mpls_route_details_t_handler_json
18977   (vl_api_mpls_route_details_t * mp)
18978 {
18979   vat_main_t *vam = &vat_main;
18980   int count = ntohl (mp->mr_route.mr_n_paths);
18981   vat_json_node_t *node = NULL;
18982   vl_api_fib_path_t *fp;
18983   int i;
18984
18985   if (VAT_JSON_ARRAY != vam->json_tree.type)
18986     {
18987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18988       vat_json_init_array (&vam->json_tree);
18989     }
18990   node = vat_json_array_add (&vam->json_tree);
18991
18992   vat_json_init_object (node);
18993   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18994   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18995   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18996   vat_json_object_add_uint (node, "path_count", count);
18997   fp = mp->mr_route.mr_paths;
18998   for (i = 0; i < count; i++)
18999     {
19000       vl_api_mpls_fib_path_json_print (node, fp);
19001       fp++;
19002     }
19003 }
19004
19005 static int
19006 api_mpls_route_dump (vat_main_t * vam)
19007 {
19008   unformat_input_t *input = vam->input;
19009   vl_api_mpls_route_dump_t *mp;
19010   vl_api_control_ping_t *mp_ping;
19011   u32 table_id;
19012   int ret;
19013
19014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19015     {
19016       if (unformat (input, "table_id %d", &table_id))
19017         ;
19018       else
19019         break;
19020     }
19021   if (table_id == ~0)
19022     {
19023       errmsg ("missing table id");
19024       return -99;
19025     }
19026
19027   M (MPLS_ROUTE_DUMP, mp);
19028
19029   mp->table.mt_table_id = ntohl (table_id);
19030   S (mp);
19031
19032   /* Use a control ping for synchronization */
19033   MPING (CONTROL_PING, mp_ping);
19034   S (mp_ping);
19035
19036   W (ret);
19037   return ret;
19038 }
19039
19040 #define vl_api_ip_table_details_t_endian vl_noop_handler
19041 #define vl_api_ip_table_details_t_print vl_noop_handler
19042
19043 static void
19044 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19045 {
19046   vat_main_t *vam = &vat_main;
19047
19048   print (vam->ofp,
19049          "%s; table-id %d, prefix %U/%d",
19050          mp->table.name, ntohl (mp->table.table_id));
19051 }
19052
19053
19054 static void vl_api_ip_table_details_t_handler_json
19055   (vl_api_ip_table_details_t * mp)
19056 {
19057   vat_main_t *vam = &vat_main;
19058   vat_json_node_t *node = NULL;
19059
19060   if (VAT_JSON_ARRAY != vam->json_tree.type)
19061     {
19062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19063       vat_json_init_array (&vam->json_tree);
19064     }
19065   node = vat_json_array_add (&vam->json_tree);
19066
19067   vat_json_init_object (node);
19068   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19069 }
19070
19071 static int
19072 api_ip_table_dump (vat_main_t * vam)
19073 {
19074   vl_api_ip_table_dump_t *mp;
19075   vl_api_control_ping_t *mp_ping;
19076   int ret;
19077
19078   M (IP_TABLE_DUMP, mp);
19079   S (mp);
19080
19081   /* Use a control ping for synchronization */
19082   MPING (CONTROL_PING, mp_ping);
19083   S (mp_ping);
19084
19085   W (ret);
19086   return ret;
19087 }
19088
19089 static int
19090 api_ip_mtable_dump (vat_main_t * vam)
19091 {
19092   vl_api_ip_mtable_dump_t *mp;
19093   vl_api_control_ping_t *mp_ping;
19094   int ret;
19095
19096   M (IP_MTABLE_DUMP, mp);
19097   S (mp);
19098
19099   /* Use a control ping for synchronization */
19100   MPING (CONTROL_PING, mp_ping);
19101   S (mp_ping);
19102
19103   W (ret);
19104   return ret;
19105 }
19106
19107 static int
19108 api_ip_mroute_dump (vat_main_t * vam)
19109 {
19110   unformat_input_t *input = vam->input;
19111   vl_api_control_ping_t *mp_ping;
19112   vl_api_ip_mroute_dump_t *mp;
19113   int ret, is_ip6;
19114   u32 table_id;
19115
19116   is_ip6 = 0;
19117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19118     {
19119       if (unformat (input, "table_id %d", &table_id))
19120         ;
19121       else if (unformat (input, "ip6"))
19122         is_ip6 = 1;
19123       else if (unformat (input, "ip4"))
19124         is_ip6 = 0;
19125       else
19126         break;
19127     }
19128   if (table_id == ~0)
19129     {
19130       errmsg ("missing table id");
19131       return -99;
19132     }
19133
19134   M (IP_MROUTE_DUMP, mp);
19135   mp->table.table_id = table_id;
19136   mp->table.is_ip6 = is_ip6;
19137   S (mp);
19138
19139   /* Use a control ping for synchronization */
19140   MPING (CONTROL_PING, mp_ping);
19141   S (mp_ping);
19142
19143   W (ret);
19144   return ret;
19145 }
19146
19147 static void vl_api_ip_neighbor_details_t_handler
19148   (vl_api_ip_neighbor_details_t * mp)
19149 {
19150   vat_main_t *vam = &vat_main;
19151
19152   print (vam->ofp, "%c %U %U",
19153          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19154          format_vl_api_mac_address, &mp->neighbor.mac_address,
19155          format_vl_api_address, &mp->neighbor.ip_address);
19156 }
19157
19158 static void vl_api_ip_neighbor_details_t_handler_json
19159   (vl_api_ip_neighbor_details_t * mp)
19160 {
19161
19162   vat_main_t *vam = &vat_main;
19163   vat_json_node_t *node;
19164
19165   if (VAT_JSON_ARRAY != vam->json_tree.type)
19166     {
19167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19168       vat_json_init_array (&vam->json_tree);
19169     }
19170   node = vat_json_array_add (&vam->json_tree);
19171
19172   vat_json_init_object (node);
19173   vat_json_object_add_string_copy
19174     (node, "flag",
19175      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19176       (u8 *) "static" : (u8 *) "dynamic"));
19177
19178   vat_json_object_add_string_copy (node, "link_layer",
19179                                    format (0, "%U", format_vl_api_mac_address,
19180                                            &mp->neighbor.mac_address));
19181   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19182 }
19183
19184 static int
19185 api_ip_neighbor_dump (vat_main_t * vam)
19186 {
19187   unformat_input_t *i = vam->input;
19188   vl_api_ip_neighbor_dump_t *mp;
19189   vl_api_control_ping_t *mp_ping;
19190   u8 is_ipv6 = 0;
19191   u32 sw_if_index = ~0;
19192   int ret;
19193
19194   /* Parse args required to build the message */
19195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19196     {
19197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19198         ;
19199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19200         ;
19201       else if (unformat (i, "ip6"))
19202         is_ipv6 = 1;
19203       else
19204         break;
19205     }
19206
19207   if (sw_if_index == ~0)
19208     {
19209       errmsg ("missing interface name or sw_if_index");
19210       return -99;
19211     }
19212
19213   M (IP_NEIGHBOR_DUMP, mp);
19214   mp->is_ipv6 = (u8) is_ipv6;
19215   mp->sw_if_index = ntohl (sw_if_index);
19216   S (mp);
19217
19218   /* Use a control ping for synchronization */
19219   MPING (CONTROL_PING, mp_ping);
19220   S (mp_ping);
19221
19222   W (ret);
19223   return ret;
19224 }
19225
19226 #define vl_api_ip_route_details_t_endian vl_noop_handler
19227 #define vl_api_ip_route_details_t_print vl_noop_handler
19228
19229 static void
19230 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19231 {
19232   vat_main_t *vam = &vat_main;
19233   u8 count = mp->route.n_paths;
19234   vl_api_fib_path_t *fp;
19235   int i;
19236
19237   print (vam->ofp,
19238          "table-id %d, prefix %U/%d",
19239          ntohl (mp->route.table_id),
19240          format_ip46_address,
19241          mp->route.prefix.address, mp->route.prefix.address_length);
19242   for (i = 0; i < count; i++)
19243     {
19244       fp = &mp->route.paths[i];
19245
19246       vl_api_fib_path_print (vam, fp);
19247       fp++;
19248     }
19249 }
19250
19251 static void vl_api_ip_route_details_t_handler_json
19252   (vl_api_ip_route_details_t * mp)
19253 {
19254   vat_main_t *vam = &vat_main;
19255   u8 count = mp->route.n_paths;
19256   vat_json_node_t *node = NULL;
19257   struct in_addr ip4;
19258   struct in6_addr ip6;
19259   vl_api_fib_path_t *fp;
19260   int i;
19261
19262   if (VAT_JSON_ARRAY != vam->json_tree.type)
19263     {
19264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19265       vat_json_init_array (&vam->json_tree);
19266     }
19267   node = vat_json_array_add (&vam->json_tree);
19268
19269   vat_json_init_object (node);
19270   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19271   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19272     {
19273       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19274       vat_json_object_add_ip6 (node, "prefix", ip6);
19275     }
19276   else
19277     {
19278       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19279       vat_json_object_add_ip4 (node, "prefix", ip4);
19280     }
19281   vat_json_object_add_uint (node, "mask_length",
19282                             mp->route.prefix.address_length);
19283   vat_json_object_add_uint (node, "path_count", count);
19284   for (i = 0; i < count; i++)
19285     {
19286       fp = &mp->route.paths[i];
19287       vl_api_mpls_fib_path_json_print (node, fp);
19288     }
19289 }
19290
19291 static int
19292 api_ip_route_dump (vat_main_t * vam)
19293 {
19294   unformat_input_t *input = vam->input;
19295   vl_api_ip_route_dump_t *mp;
19296   vl_api_control_ping_t *mp_ping;
19297   u32 table_id;
19298   u8 is_ip6;
19299   int ret;
19300
19301   is_ip6 = 0;
19302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19303     {
19304       if (unformat (input, "table_id %d", &table_id))
19305         ;
19306       else if (unformat (input, "ip6"))
19307         is_ip6 = 1;
19308       else if (unformat (input, "ip4"))
19309         is_ip6 = 0;
19310       else
19311         break;
19312     }
19313   if (table_id == ~0)
19314     {
19315       errmsg ("missing table id");
19316       return -99;
19317     }
19318
19319   M (IP_ROUTE_DUMP, mp);
19320
19321   mp->table.table_id = table_id;
19322   mp->table.is_ip6 = is_ip6;
19323
19324   S (mp);
19325
19326   /* Use a control ping for synchronization */
19327   MPING (CONTROL_PING, mp_ping);
19328   S (mp_ping);
19329
19330   W (ret);
19331   return ret;
19332 }
19333
19334 int
19335 api_classify_table_ids (vat_main_t * vam)
19336 {
19337   vl_api_classify_table_ids_t *mp;
19338   int ret;
19339
19340   /* Construct the API message */
19341   M (CLASSIFY_TABLE_IDS, mp);
19342   mp->context = 0;
19343
19344   S (mp);
19345   W (ret);
19346   return ret;
19347 }
19348
19349 int
19350 api_classify_table_by_interface (vat_main_t * vam)
19351 {
19352   unformat_input_t *input = vam->input;
19353   vl_api_classify_table_by_interface_t *mp;
19354
19355   u32 sw_if_index = ~0;
19356   int ret;
19357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19358     {
19359       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19360         ;
19361       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19362         ;
19363       else
19364         break;
19365     }
19366   if (sw_if_index == ~0)
19367     {
19368       errmsg ("missing interface name or sw_if_index");
19369       return -99;
19370     }
19371
19372   /* Construct the API message */
19373   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19374   mp->context = 0;
19375   mp->sw_if_index = ntohl (sw_if_index);
19376
19377   S (mp);
19378   W (ret);
19379   return ret;
19380 }
19381
19382 int
19383 api_classify_table_info (vat_main_t * vam)
19384 {
19385   unformat_input_t *input = vam->input;
19386   vl_api_classify_table_info_t *mp;
19387
19388   u32 table_id = ~0;
19389   int ret;
19390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19391     {
19392       if (unformat (input, "table_id %d", &table_id))
19393         ;
19394       else
19395         break;
19396     }
19397   if (table_id == ~0)
19398     {
19399       errmsg ("missing table id");
19400       return -99;
19401     }
19402
19403   /* Construct the API message */
19404   M (CLASSIFY_TABLE_INFO, mp);
19405   mp->context = 0;
19406   mp->table_id = ntohl (table_id);
19407
19408   S (mp);
19409   W (ret);
19410   return ret;
19411 }
19412
19413 int
19414 api_classify_session_dump (vat_main_t * vam)
19415 {
19416   unformat_input_t *input = vam->input;
19417   vl_api_classify_session_dump_t *mp;
19418   vl_api_control_ping_t *mp_ping;
19419
19420   u32 table_id = ~0;
19421   int ret;
19422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19423     {
19424       if (unformat (input, "table_id %d", &table_id))
19425         ;
19426       else
19427         break;
19428     }
19429   if (table_id == ~0)
19430     {
19431       errmsg ("missing table id");
19432       return -99;
19433     }
19434
19435   /* Construct the API message */
19436   M (CLASSIFY_SESSION_DUMP, mp);
19437   mp->context = 0;
19438   mp->table_id = ntohl (table_id);
19439   S (mp);
19440
19441   /* Use a control ping for synchronization */
19442   MPING (CONTROL_PING, mp_ping);
19443   S (mp_ping);
19444
19445   W (ret);
19446   return ret;
19447 }
19448
19449 static void
19450 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19451 {
19452   vat_main_t *vam = &vat_main;
19453
19454   print (vam->ofp, "collector_address %U, collector_port %d, "
19455          "src_address %U, vrf_id %d, path_mtu %u, "
19456          "template_interval %u, udp_checksum %d",
19457          format_ip4_address, mp->collector_address,
19458          ntohs (mp->collector_port),
19459          format_ip4_address, mp->src_address,
19460          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19461          ntohl (mp->template_interval), mp->udp_checksum);
19462
19463   vam->retval = 0;
19464   vam->result_ready = 1;
19465 }
19466
19467 static void
19468   vl_api_ipfix_exporter_details_t_handler_json
19469   (vl_api_ipfix_exporter_details_t * mp)
19470 {
19471   vat_main_t *vam = &vat_main;
19472   vat_json_node_t node;
19473   struct in_addr collector_address;
19474   struct in_addr src_address;
19475
19476   vat_json_init_object (&node);
19477   clib_memcpy (&collector_address, &mp->collector_address,
19478                sizeof (collector_address));
19479   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19480   vat_json_object_add_uint (&node, "collector_port",
19481                             ntohs (mp->collector_port));
19482   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19483   vat_json_object_add_ip4 (&node, "src_address", src_address);
19484   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19485   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19486   vat_json_object_add_uint (&node, "template_interval",
19487                             ntohl (mp->template_interval));
19488   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19489
19490   vat_json_print (vam->ofp, &node);
19491   vat_json_free (&node);
19492   vam->retval = 0;
19493   vam->result_ready = 1;
19494 }
19495
19496 int
19497 api_ipfix_exporter_dump (vat_main_t * vam)
19498 {
19499   vl_api_ipfix_exporter_dump_t *mp;
19500   int ret;
19501
19502   /* Construct the API message */
19503   M (IPFIX_EXPORTER_DUMP, mp);
19504   mp->context = 0;
19505
19506   S (mp);
19507   W (ret);
19508   return ret;
19509 }
19510
19511 static int
19512 api_ipfix_classify_stream_dump (vat_main_t * vam)
19513 {
19514   vl_api_ipfix_classify_stream_dump_t *mp;
19515   int ret;
19516
19517   /* Construct the API message */
19518   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19519   mp->context = 0;
19520
19521   S (mp);
19522   W (ret);
19523   return ret;
19524   /* NOTREACHED */
19525   return 0;
19526 }
19527
19528 static void
19529   vl_api_ipfix_classify_stream_details_t_handler
19530   (vl_api_ipfix_classify_stream_details_t * mp)
19531 {
19532   vat_main_t *vam = &vat_main;
19533   print (vam->ofp, "domain_id %d, src_port %d",
19534          ntohl (mp->domain_id), ntohs (mp->src_port));
19535   vam->retval = 0;
19536   vam->result_ready = 1;
19537 }
19538
19539 static void
19540   vl_api_ipfix_classify_stream_details_t_handler_json
19541   (vl_api_ipfix_classify_stream_details_t * mp)
19542 {
19543   vat_main_t *vam = &vat_main;
19544   vat_json_node_t node;
19545
19546   vat_json_init_object (&node);
19547   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19548   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19549
19550   vat_json_print (vam->ofp, &node);
19551   vat_json_free (&node);
19552   vam->retval = 0;
19553   vam->result_ready = 1;
19554 }
19555
19556 static int
19557 api_ipfix_classify_table_dump (vat_main_t * vam)
19558 {
19559   vl_api_ipfix_classify_table_dump_t *mp;
19560   vl_api_control_ping_t *mp_ping;
19561   int ret;
19562
19563   if (!vam->json_output)
19564     {
19565       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19566              "transport_protocol");
19567     }
19568
19569   /* Construct the API message */
19570   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19571
19572   /* send it... */
19573   S (mp);
19574
19575   /* Use a control ping for synchronization */
19576   MPING (CONTROL_PING, mp_ping);
19577   S (mp_ping);
19578
19579   W (ret);
19580   return ret;
19581 }
19582
19583 static void
19584   vl_api_ipfix_classify_table_details_t_handler
19585   (vl_api_ipfix_classify_table_details_t * mp)
19586 {
19587   vat_main_t *vam = &vat_main;
19588   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19589          mp->transport_protocol);
19590 }
19591
19592 static void
19593   vl_api_ipfix_classify_table_details_t_handler_json
19594   (vl_api_ipfix_classify_table_details_t * mp)
19595 {
19596   vat_json_node_t *node = NULL;
19597   vat_main_t *vam = &vat_main;
19598
19599   if (VAT_JSON_ARRAY != vam->json_tree.type)
19600     {
19601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19602       vat_json_init_array (&vam->json_tree);
19603     }
19604
19605   node = vat_json_array_add (&vam->json_tree);
19606   vat_json_init_object (node);
19607
19608   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19609   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19610   vat_json_object_add_uint (node, "transport_protocol",
19611                             mp->transport_protocol);
19612 }
19613
19614 static int
19615 api_sw_interface_span_enable_disable (vat_main_t * vam)
19616 {
19617   unformat_input_t *i = vam->input;
19618   vl_api_sw_interface_span_enable_disable_t *mp;
19619   u32 src_sw_if_index = ~0;
19620   u32 dst_sw_if_index = ~0;
19621   u8 state = 3;
19622   int ret;
19623   u8 is_l2 = 0;
19624
19625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19626     {
19627       if (unformat
19628           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19629         ;
19630       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19631         ;
19632       else
19633         if (unformat
19634             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19635         ;
19636       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19637         ;
19638       else if (unformat (i, "disable"))
19639         state = 0;
19640       else if (unformat (i, "rx"))
19641         state = 1;
19642       else if (unformat (i, "tx"))
19643         state = 2;
19644       else if (unformat (i, "both"))
19645         state = 3;
19646       else if (unformat (i, "l2"))
19647         is_l2 = 1;
19648       else
19649         break;
19650     }
19651
19652   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19653
19654   mp->sw_if_index_from = htonl (src_sw_if_index);
19655   mp->sw_if_index_to = htonl (dst_sw_if_index);
19656   mp->state = state;
19657   mp->is_l2 = is_l2;
19658
19659   S (mp);
19660   W (ret);
19661   return ret;
19662 }
19663
19664 static void
19665 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19666                                             * mp)
19667 {
19668   vat_main_t *vam = &vat_main;
19669   u8 *sw_if_from_name = 0;
19670   u8 *sw_if_to_name = 0;
19671   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19672   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19673   char *states[] = { "none", "rx", "tx", "both" };
19674   hash_pair_t *p;
19675
19676   /* *INDENT-OFF* */
19677   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19678   ({
19679     if ((u32) p->value[0] == sw_if_index_from)
19680       {
19681         sw_if_from_name = (u8 *)(p->key);
19682         if (sw_if_to_name)
19683           break;
19684       }
19685     if ((u32) p->value[0] == sw_if_index_to)
19686       {
19687         sw_if_to_name = (u8 *)(p->key);
19688         if (sw_if_from_name)
19689           break;
19690       }
19691   }));
19692   /* *INDENT-ON* */
19693   print (vam->ofp, "%20s => %20s (%s) %s",
19694          sw_if_from_name, sw_if_to_name, states[mp->state],
19695          mp->is_l2 ? "l2" : "device");
19696 }
19697
19698 static void
19699   vl_api_sw_interface_span_details_t_handler_json
19700   (vl_api_sw_interface_span_details_t * mp)
19701 {
19702   vat_main_t *vam = &vat_main;
19703   vat_json_node_t *node = NULL;
19704   u8 *sw_if_from_name = 0;
19705   u8 *sw_if_to_name = 0;
19706   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19707   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19708   hash_pair_t *p;
19709
19710   /* *INDENT-OFF* */
19711   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19712   ({
19713     if ((u32) p->value[0] == sw_if_index_from)
19714       {
19715         sw_if_from_name = (u8 *)(p->key);
19716         if (sw_if_to_name)
19717           break;
19718       }
19719     if ((u32) p->value[0] == sw_if_index_to)
19720       {
19721         sw_if_to_name = (u8 *)(p->key);
19722         if (sw_if_from_name)
19723           break;
19724       }
19725   }));
19726   /* *INDENT-ON* */
19727
19728   if (VAT_JSON_ARRAY != vam->json_tree.type)
19729     {
19730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19731       vat_json_init_array (&vam->json_tree);
19732     }
19733   node = vat_json_array_add (&vam->json_tree);
19734
19735   vat_json_init_object (node);
19736   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19737   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19738   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19739   if (0 != sw_if_to_name)
19740     {
19741       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19742     }
19743   vat_json_object_add_uint (node, "state", mp->state);
19744   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19745 }
19746
19747 static int
19748 api_sw_interface_span_dump (vat_main_t * vam)
19749 {
19750   unformat_input_t *input = vam->input;
19751   vl_api_sw_interface_span_dump_t *mp;
19752   vl_api_control_ping_t *mp_ping;
19753   u8 is_l2 = 0;
19754   int ret;
19755
19756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19757     {
19758       if (unformat (input, "l2"))
19759         is_l2 = 1;
19760       else
19761         break;
19762     }
19763
19764   M (SW_INTERFACE_SPAN_DUMP, mp);
19765   mp->is_l2 = is_l2;
19766   S (mp);
19767
19768   /* Use a control ping for synchronization */
19769   MPING (CONTROL_PING, mp_ping);
19770   S (mp_ping);
19771
19772   W (ret);
19773   return ret;
19774 }
19775
19776 int
19777 api_pg_create_interface (vat_main_t * vam)
19778 {
19779   unformat_input_t *input = vam->input;
19780   vl_api_pg_create_interface_t *mp;
19781
19782   u32 if_id = ~0;
19783   int ret;
19784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19785     {
19786       if (unformat (input, "if_id %d", &if_id))
19787         ;
19788       else
19789         break;
19790     }
19791   if (if_id == ~0)
19792     {
19793       errmsg ("missing pg interface index");
19794       return -99;
19795     }
19796
19797   /* Construct the API message */
19798   M (PG_CREATE_INTERFACE, mp);
19799   mp->context = 0;
19800   mp->interface_id = ntohl (if_id);
19801
19802   S (mp);
19803   W (ret);
19804   return ret;
19805 }
19806
19807 int
19808 api_pg_capture (vat_main_t * vam)
19809 {
19810   unformat_input_t *input = vam->input;
19811   vl_api_pg_capture_t *mp;
19812
19813   u32 if_id = ~0;
19814   u8 enable = 1;
19815   u32 count = 1;
19816   u8 pcap_file_set = 0;
19817   u8 *pcap_file = 0;
19818   int ret;
19819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19820     {
19821       if (unformat (input, "if_id %d", &if_id))
19822         ;
19823       else if (unformat (input, "pcap %s", &pcap_file))
19824         pcap_file_set = 1;
19825       else if (unformat (input, "count %d", &count))
19826         ;
19827       else if (unformat (input, "disable"))
19828         enable = 0;
19829       else
19830         break;
19831     }
19832   if (if_id == ~0)
19833     {
19834       errmsg ("missing pg interface index");
19835       return -99;
19836     }
19837   if (pcap_file_set > 0)
19838     {
19839       if (vec_len (pcap_file) > 255)
19840         {
19841           errmsg ("pcap file name is too long");
19842           return -99;
19843         }
19844     }
19845
19846   u32 name_len = vec_len (pcap_file);
19847   /* Construct the API message */
19848   M (PG_CAPTURE, mp);
19849   mp->context = 0;
19850   mp->interface_id = ntohl (if_id);
19851   mp->is_enabled = enable;
19852   mp->count = ntohl (count);
19853   mp->pcap_name_length = ntohl (name_len);
19854   if (pcap_file_set != 0)
19855     {
19856       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19857     }
19858   vec_free (pcap_file);
19859
19860   S (mp);
19861   W (ret);
19862   return ret;
19863 }
19864
19865 int
19866 api_pg_enable_disable (vat_main_t * vam)
19867 {
19868   unformat_input_t *input = vam->input;
19869   vl_api_pg_enable_disable_t *mp;
19870
19871   u8 enable = 1;
19872   u8 stream_name_set = 0;
19873   u8 *stream_name = 0;
19874   int ret;
19875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19876     {
19877       if (unformat (input, "stream %s", &stream_name))
19878         stream_name_set = 1;
19879       else if (unformat (input, "disable"))
19880         enable = 0;
19881       else
19882         break;
19883     }
19884
19885   if (stream_name_set > 0)
19886     {
19887       if (vec_len (stream_name) > 255)
19888         {
19889           errmsg ("stream name too long");
19890           return -99;
19891         }
19892     }
19893
19894   u32 name_len = vec_len (stream_name);
19895   /* Construct the API message */
19896   M (PG_ENABLE_DISABLE, mp);
19897   mp->context = 0;
19898   mp->is_enabled = enable;
19899   if (stream_name_set != 0)
19900     {
19901       mp->stream_name_length = ntohl (name_len);
19902       clib_memcpy (mp->stream_name, stream_name, name_len);
19903     }
19904   vec_free (stream_name);
19905
19906   S (mp);
19907   W (ret);
19908   return ret;
19909 }
19910
19911 int
19912 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19913 {
19914   unformat_input_t *input = vam->input;
19915   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19916
19917   u16 *low_ports = 0;
19918   u16 *high_ports = 0;
19919   u16 this_low;
19920   u16 this_hi;
19921   vl_api_prefix_t prefix;
19922   u32 tmp, tmp2;
19923   u8 prefix_set = 0;
19924   u32 vrf_id = ~0;
19925   u8 is_add = 1;
19926   int ret;
19927
19928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19929     {
19930       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19931         prefix_set = 1;
19932       else if (unformat (input, "vrf %d", &vrf_id))
19933         ;
19934       else if (unformat (input, "del"))
19935         is_add = 0;
19936       else if (unformat (input, "port %d", &tmp))
19937         {
19938           if (tmp == 0 || tmp > 65535)
19939             {
19940               errmsg ("port %d out of range", tmp);
19941               return -99;
19942             }
19943           this_low = tmp;
19944           this_hi = this_low + 1;
19945           vec_add1 (low_ports, this_low);
19946           vec_add1 (high_ports, this_hi);
19947         }
19948       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19949         {
19950           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19951             {
19952               errmsg ("incorrect range parameters");
19953               return -99;
19954             }
19955           this_low = tmp;
19956           /* Note: in debug CLI +1 is added to high before
19957              passing to real fn that does "the work"
19958              (ip_source_and_port_range_check_add_del).
19959              This fn is a wrapper around the binary API fn a
19960              control plane will call, which expects this increment
19961              to have occurred. Hence letting the binary API control
19962              plane fn do the increment for consistency between VAT
19963              and other control planes.
19964            */
19965           this_hi = tmp2;
19966           vec_add1 (low_ports, this_low);
19967           vec_add1 (high_ports, this_hi);
19968         }
19969       else
19970         break;
19971     }
19972
19973   if (prefix_set == 0)
19974     {
19975       errmsg ("<address>/<mask> not specified");
19976       return -99;
19977     }
19978
19979   if (vrf_id == ~0)
19980     {
19981       errmsg ("VRF ID required, not specified");
19982       return -99;
19983     }
19984
19985   if (vrf_id == 0)
19986     {
19987       errmsg
19988         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19989       return -99;
19990     }
19991
19992   if (vec_len (low_ports) == 0)
19993     {
19994       errmsg ("At least one port or port range required");
19995       return -99;
19996     }
19997
19998   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19999
20000   mp->is_add = is_add;
20001
20002   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20003
20004   mp->number_of_ranges = vec_len (low_ports);
20005
20006   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20007   vec_free (low_ports);
20008
20009   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20010   vec_free (high_ports);
20011
20012   mp->vrf_id = ntohl (vrf_id);
20013
20014   S (mp);
20015   W (ret);
20016   return ret;
20017 }
20018
20019 int
20020 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20021 {
20022   unformat_input_t *input = vam->input;
20023   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20024   u32 sw_if_index = ~0;
20025   int vrf_set = 0;
20026   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20027   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20028   u8 is_add = 1;
20029   int ret;
20030
20031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20032     {
20033       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20034         ;
20035       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20036         ;
20037       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20038         vrf_set = 1;
20039       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20040         vrf_set = 1;
20041       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20042         vrf_set = 1;
20043       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20044         vrf_set = 1;
20045       else if (unformat (input, "del"))
20046         is_add = 0;
20047       else
20048         break;
20049     }
20050
20051   if (sw_if_index == ~0)
20052     {
20053       errmsg ("Interface required but not specified");
20054       return -99;
20055     }
20056
20057   if (vrf_set == 0)
20058     {
20059       errmsg ("VRF ID required but not specified");
20060       return -99;
20061     }
20062
20063   if (tcp_out_vrf_id == 0
20064       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20065     {
20066       errmsg
20067         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20068       return -99;
20069     }
20070
20071   /* Construct the API message */
20072   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20073
20074   mp->sw_if_index = ntohl (sw_if_index);
20075   mp->is_add = is_add;
20076   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20077   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20078   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20079   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20080
20081   /* send it... */
20082   S (mp);
20083
20084   /* Wait for a reply... */
20085   W (ret);
20086   return ret;
20087 }
20088
20089 static int
20090 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20091 {
20092   unformat_input_t *i = vam->input;
20093   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20094   u32 local_sa_id = 0;
20095   u32 remote_sa_id = 0;
20096   vl_api_ip4_address_t src_address;
20097   vl_api_ip4_address_t dst_address;
20098   u8 is_add = 1;
20099   int ret;
20100
20101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20102     {
20103       if (unformat (i, "local_sa %d", &local_sa_id))
20104         ;
20105       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20106         ;
20107       else
20108         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20109         ;
20110       else
20111         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20112         ;
20113       else if (unformat (i, "del"))
20114         is_add = 0;
20115       else
20116         {
20117           clib_warning ("parse error '%U'", format_unformat_error, i);
20118           return -99;
20119         }
20120     }
20121
20122   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20123
20124   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20125   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20126   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20127   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20128   mp->is_add = is_add;
20129
20130   S (mp);
20131   W (ret);
20132   return ret;
20133 }
20134
20135 static int
20136 api_set_punt (vat_main_t * vam)
20137 {
20138   unformat_input_t *i = vam->input;
20139   vl_api_address_family_t af;
20140   vl_api_set_punt_t *mp;
20141   u32 protocol = ~0;
20142   u32 port = ~0;
20143   int is_add = 1;
20144   int ret;
20145
20146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20147     {
20148       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20149         ;
20150       else if (unformat (i, "protocol %d", &protocol))
20151         ;
20152       else if (unformat (i, "port %d", &port))
20153         ;
20154       else if (unformat (i, "del"))
20155         is_add = 0;
20156       else
20157         {
20158           clib_warning ("parse error '%U'", format_unformat_error, i);
20159           return -99;
20160         }
20161     }
20162
20163   M (SET_PUNT, mp);
20164
20165   mp->is_add = (u8) is_add;
20166   mp->punt.type = PUNT_API_TYPE_L4;
20167   mp->punt.punt.l4.af = af;
20168   mp->punt.punt.l4.protocol = (u8) protocol;
20169   mp->punt.punt.l4.port = htons ((u16) port);
20170
20171   S (mp);
20172   W (ret);
20173   return ret;
20174 }
20175
20176 static void vl_api_ipsec_gre_tunnel_details_t_handler
20177   (vl_api_ipsec_gre_tunnel_details_t * mp)
20178 {
20179   vat_main_t *vam = &vat_main;
20180
20181   print (vam->ofp, "%11d%15U%15U%14d%14d",
20182          ntohl (mp->tunnel.sw_if_index),
20183          format_vl_api_ip4_address, mp->tunnel.src,
20184          format_vl_api_ip4_address, mp->tunnel.dst,
20185          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20186 }
20187
20188 static void
20189 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20190                                 const char *name,
20191                                 const vl_api_ip4_address_t addr)
20192 {
20193   struct in_addr ip4;
20194
20195   clib_memcpy (&ip4, addr, sizeof (ip4));
20196   vat_json_object_add_ip4 (node, name, ip4);
20197 }
20198
20199 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20200   (vl_api_ipsec_gre_tunnel_details_t * mp)
20201 {
20202   vat_main_t *vam = &vat_main;
20203   vat_json_node_t *node = NULL;
20204
20205   if (VAT_JSON_ARRAY != vam->json_tree.type)
20206     {
20207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20208       vat_json_init_array (&vam->json_tree);
20209     }
20210   node = vat_json_array_add (&vam->json_tree);
20211
20212   vat_json_init_object (node);
20213   vat_json_object_add_uint (node, "sw_if_index",
20214                             ntohl (mp->tunnel.sw_if_index));
20215   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20216   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20217   vat_json_object_add_uint (node, "local_sa_id",
20218                             ntohl (mp->tunnel.local_sa_id));
20219   vat_json_object_add_uint (node, "remote_sa_id",
20220                             ntohl (mp->tunnel.remote_sa_id));
20221 }
20222
20223 static int
20224 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20225 {
20226   unformat_input_t *i = vam->input;
20227   vl_api_ipsec_gre_tunnel_dump_t *mp;
20228   vl_api_control_ping_t *mp_ping;
20229   u32 sw_if_index;
20230   u8 sw_if_index_set = 0;
20231   int ret;
20232
20233   /* Parse args required to build the message */
20234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20235     {
20236       if (unformat (i, "sw_if_index %d", &sw_if_index))
20237         sw_if_index_set = 1;
20238       else
20239         break;
20240     }
20241
20242   if (sw_if_index_set == 0)
20243     {
20244       sw_if_index = ~0;
20245     }
20246
20247   if (!vam->json_output)
20248     {
20249       print (vam->ofp, "%11s%15s%15s%14s%14s",
20250              "sw_if_index", "src_address", "dst_address",
20251              "local_sa_id", "remote_sa_id");
20252     }
20253
20254   /* Get list of gre-tunnel interfaces */
20255   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20256
20257   mp->sw_if_index = htonl (sw_if_index);
20258
20259   S (mp);
20260
20261   /* Use a control ping for synchronization */
20262   MPING (CONTROL_PING, mp_ping);
20263   S (mp_ping);
20264
20265   W (ret);
20266   return ret;
20267 }
20268
20269 static int
20270 api_delete_subif (vat_main_t * vam)
20271 {
20272   unformat_input_t *i = vam->input;
20273   vl_api_delete_subif_t *mp;
20274   u32 sw_if_index = ~0;
20275   int ret;
20276
20277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20278     {
20279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20280         ;
20281       if (unformat (i, "sw_if_index %d", &sw_if_index))
20282         ;
20283       else
20284         break;
20285     }
20286
20287   if (sw_if_index == ~0)
20288     {
20289       errmsg ("missing sw_if_index");
20290       return -99;
20291     }
20292
20293   /* Construct the API message */
20294   M (DELETE_SUBIF, mp);
20295   mp->sw_if_index = ntohl (sw_if_index);
20296
20297   S (mp);
20298   W (ret);
20299   return ret;
20300 }
20301
20302 #define foreach_pbb_vtr_op      \
20303 _("disable",  L2_VTR_DISABLED)  \
20304 _("pop",  L2_VTR_POP_2)         \
20305 _("push",  L2_VTR_PUSH_2)
20306
20307 static int
20308 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20309 {
20310   unformat_input_t *i = vam->input;
20311   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20312   u32 sw_if_index = ~0, vtr_op = ~0;
20313   u16 outer_tag = ~0;
20314   u8 dmac[6], smac[6];
20315   u8 dmac_set = 0, smac_set = 0;
20316   u16 vlanid = 0;
20317   u32 sid = ~0;
20318   u32 tmp;
20319   int ret;
20320
20321   /* Shut up coverity */
20322   clib_memset (dmac, 0, sizeof (dmac));
20323   clib_memset (smac, 0, sizeof (smac));
20324
20325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20326     {
20327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20328         ;
20329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20330         ;
20331       else if (unformat (i, "vtr_op %d", &vtr_op))
20332         ;
20333 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20334       foreach_pbb_vtr_op
20335 #undef _
20336         else if (unformat (i, "translate_pbb_stag"))
20337         {
20338           if (unformat (i, "%d", &tmp))
20339             {
20340               vtr_op = L2_VTR_TRANSLATE_2_1;
20341               outer_tag = tmp;
20342             }
20343           else
20344             {
20345               errmsg
20346                 ("translate_pbb_stag operation requires outer tag definition");
20347               return -99;
20348             }
20349         }
20350       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20351         dmac_set++;
20352       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20353         smac_set++;
20354       else if (unformat (i, "sid %d", &sid))
20355         ;
20356       else if (unformat (i, "vlanid %d", &tmp))
20357         vlanid = tmp;
20358       else
20359         {
20360           clib_warning ("parse error '%U'", format_unformat_error, i);
20361           return -99;
20362         }
20363     }
20364
20365   if ((sw_if_index == ~0) || (vtr_op == ~0))
20366     {
20367       errmsg ("missing sw_if_index or vtr operation");
20368       return -99;
20369     }
20370   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20371       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20372     {
20373       errmsg
20374         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20375       return -99;
20376     }
20377
20378   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20379   mp->sw_if_index = ntohl (sw_if_index);
20380   mp->vtr_op = ntohl (vtr_op);
20381   mp->outer_tag = ntohs (outer_tag);
20382   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20383   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20384   mp->b_vlanid = ntohs (vlanid);
20385   mp->i_sid = ntohl (sid);
20386
20387   S (mp);
20388   W (ret);
20389   return ret;
20390 }
20391
20392 static int
20393 api_flow_classify_set_interface (vat_main_t * vam)
20394 {
20395   unformat_input_t *i = vam->input;
20396   vl_api_flow_classify_set_interface_t *mp;
20397   u32 sw_if_index;
20398   int sw_if_index_set;
20399   u32 ip4_table_index = ~0;
20400   u32 ip6_table_index = ~0;
20401   u8 is_add = 1;
20402   int ret;
20403
20404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20405     {
20406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20407         sw_if_index_set = 1;
20408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20409         sw_if_index_set = 1;
20410       else if (unformat (i, "del"))
20411         is_add = 0;
20412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20413         ;
20414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20415         ;
20416       else
20417         {
20418           clib_warning ("parse error '%U'", format_unformat_error, i);
20419           return -99;
20420         }
20421     }
20422
20423   if (sw_if_index_set == 0)
20424     {
20425       errmsg ("missing interface name or sw_if_index");
20426       return -99;
20427     }
20428
20429   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20430
20431   mp->sw_if_index = ntohl (sw_if_index);
20432   mp->ip4_table_index = ntohl (ip4_table_index);
20433   mp->ip6_table_index = ntohl (ip6_table_index);
20434   mp->is_add = is_add;
20435
20436   S (mp);
20437   W (ret);
20438   return ret;
20439 }
20440
20441 static int
20442 api_flow_classify_dump (vat_main_t * vam)
20443 {
20444   unformat_input_t *i = vam->input;
20445   vl_api_flow_classify_dump_t *mp;
20446   vl_api_control_ping_t *mp_ping;
20447   u8 type = FLOW_CLASSIFY_N_TABLES;
20448   int ret;
20449
20450   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20451     ;
20452   else
20453     {
20454       errmsg ("classify table type must be specified");
20455       return -99;
20456     }
20457
20458   if (!vam->json_output)
20459     {
20460       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20461     }
20462
20463   M (FLOW_CLASSIFY_DUMP, mp);
20464   mp->type = type;
20465   /* send it... */
20466   S (mp);
20467
20468   /* Use a control ping for synchronization */
20469   MPING (CONTROL_PING, mp_ping);
20470   S (mp_ping);
20471
20472   /* Wait for a reply... */
20473   W (ret);
20474   return ret;
20475 }
20476
20477 static int
20478 api_feature_enable_disable (vat_main_t * vam)
20479 {
20480   unformat_input_t *i = vam->input;
20481   vl_api_feature_enable_disable_t *mp;
20482   u8 *arc_name = 0;
20483   u8 *feature_name = 0;
20484   u32 sw_if_index = ~0;
20485   u8 enable = 1;
20486   int ret;
20487
20488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20489     {
20490       if (unformat (i, "arc_name %s", &arc_name))
20491         ;
20492       else if (unformat (i, "feature_name %s", &feature_name))
20493         ;
20494       else
20495         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20496         ;
20497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20498         ;
20499       else if (unformat (i, "disable"))
20500         enable = 0;
20501       else
20502         break;
20503     }
20504
20505   if (arc_name == 0)
20506     {
20507       errmsg ("missing arc name");
20508       return -99;
20509     }
20510   if (vec_len (arc_name) > 63)
20511     {
20512       errmsg ("arc name too long");
20513     }
20514
20515   if (feature_name == 0)
20516     {
20517       errmsg ("missing feature name");
20518       return -99;
20519     }
20520   if (vec_len (feature_name) > 63)
20521     {
20522       errmsg ("feature name too long");
20523     }
20524
20525   if (sw_if_index == ~0)
20526     {
20527       errmsg ("missing interface name or sw_if_index");
20528       return -99;
20529     }
20530
20531   /* Construct the API message */
20532   M (FEATURE_ENABLE_DISABLE, mp);
20533   mp->sw_if_index = ntohl (sw_if_index);
20534   mp->enable = enable;
20535   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20536   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20537   vec_free (arc_name);
20538   vec_free (feature_name);
20539
20540   S (mp);
20541   W (ret);
20542   return ret;
20543 }
20544
20545 static int
20546 api_sw_interface_tag_add_del (vat_main_t * vam)
20547 {
20548   unformat_input_t *i = vam->input;
20549   vl_api_sw_interface_tag_add_del_t *mp;
20550   u32 sw_if_index = ~0;
20551   u8 *tag = 0;
20552   u8 enable = 1;
20553   int ret;
20554
20555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20556     {
20557       if (unformat (i, "tag %s", &tag))
20558         ;
20559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20560         ;
20561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20562         ;
20563       else if (unformat (i, "del"))
20564         enable = 0;
20565       else
20566         break;
20567     }
20568
20569   if (sw_if_index == ~0)
20570     {
20571       errmsg ("missing interface name or sw_if_index");
20572       return -99;
20573     }
20574
20575   if (enable && (tag == 0))
20576     {
20577       errmsg ("no tag specified");
20578       return -99;
20579     }
20580
20581   /* Construct the API message */
20582   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20583   mp->sw_if_index = ntohl (sw_if_index);
20584   mp->is_add = enable;
20585   if (enable)
20586     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20587   vec_free (tag);
20588
20589   S (mp);
20590   W (ret);
20591   return ret;
20592 }
20593
20594 static void vl_api_l2_xconnect_details_t_handler
20595   (vl_api_l2_xconnect_details_t * mp)
20596 {
20597   vat_main_t *vam = &vat_main;
20598
20599   print (vam->ofp, "%15d%15d",
20600          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20601 }
20602
20603 static void vl_api_l2_xconnect_details_t_handler_json
20604   (vl_api_l2_xconnect_details_t * mp)
20605 {
20606   vat_main_t *vam = &vat_main;
20607   vat_json_node_t *node = NULL;
20608
20609   if (VAT_JSON_ARRAY != vam->json_tree.type)
20610     {
20611       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20612       vat_json_init_array (&vam->json_tree);
20613     }
20614   node = vat_json_array_add (&vam->json_tree);
20615
20616   vat_json_init_object (node);
20617   vat_json_object_add_uint (node, "rx_sw_if_index",
20618                             ntohl (mp->rx_sw_if_index));
20619   vat_json_object_add_uint (node, "tx_sw_if_index",
20620                             ntohl (mp->tx_sw_if_index));
20621 }
20622
20623 static int
20624 api_l2_xconnect_dump (vat_main_t * vam)
20625 {
20626   vl_api_l2_xconnect_dump_t *mp;
20627   vl_api_control_ping_t *mp_ping;
20628   int ret;
20629
20630   if (!vam->json_output)
20631     {
20632       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20633     }
20634
20635   M (L2_XCONNECT_DUMP, mp);
20636
20637   S (mp);
20638
20639   /* Use a control ping for synchronization */
20640   MPING (CONTROL_PING, mp_ping);
20641   S (mp_ping);
20642
20643   W (ret);
20644   return ret;
20645 }
20646
20647 static int
20648 api_hw_interface_set_mtu (vat_main_t * vam)
20649 {
20650   unformat_input_t *i = vam->input;
20651   vl_api_hw_interface_set_mtu_t *mp;
20652   u32 sw_if_index = ~0;
20653   u32 mtu = 0;
20654   int ret;
20655
20656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20657     {
20658       if (unformat (i, "mtu %d", &mtu))
20659         ;
20660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20661         ;
20662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20663         ;
20664       else
20665         break;
20666     }
20667
20668   if (sw_if_index == ~0)
20669     {
20670       errmsg ("missing interface name or sw_if_index");
20671       return -99;
20672     }
20673
20674   if (mtu == 0)
20675     {
20676       errmsg ("no mtu specified");
20677       return -99;
20678     }
20679
20680   /* Construct the API message */
20681   M (HW_INTERFACE_SET_MTU, mp);
20682   mp->sw_if_index = ntohl (sw_if_index);
20683   mp->mtu = ntohs ((u16) mtu);
20684
20685   S (mp);
20686   W (ret);
20687   return ret;
20688 }
20689
20690 static int
20691 api_p2p_ethernet_add (vat_main_t * vam)
20692 {
20693   unformat_input_t *i = vam->input;
20694   vl_api_p2p_ethernet_add_t *mp;
20695   u32 parent_if_index = ~0;
20696   u32 sub_id = ~0;
20697   u8 remote_mac[6];
20698   u8 mac_set = 0;
20699   int ret;
20700
20701   clib_memset (remote_mac, 0, sizeof (remote_mac));
20702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20703     {
20704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20705         ;
20706       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20707         ;
20708       else
20709         if (unformat
20710             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20711         mac_set++;
20712       else if (unformat (i, "sub_id %d", &sub_id))
20713         ;
20714       else
20715         {
20716           clib_warning ("parse error '%U'", format_unformat_error, i);
20717           return -99;
20718         }
20719     }
20720
20721   if (parent_if_index == ~0)
20722     {
20723       errmsg ("missing interface name or sw_if_index");
20724       return -99;
20725     }
20726   if (mac_set == 0)
20727     {
20728       errmsg ("missing remote mac address");
20729       return -99;
20730     }
20731   if (sub_id == ~0)
20732     {
20733       errmsg ("missing sub-interface id");
20734       return -99;
20735     }
20736
20737   M (P2P_ETHERNET_ADD, mp);
20738   mp->parent_if_index = ntohl (parent_if_index);
20739   mp->subif_id = ntohl (sub_id);
20740   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20741
20742   S (mp);
20743   W (ret);
20744   return ret;
20745 }
20746
20747 static int
20748 api_p2p_ethernet_del (vat_main_t * vam)
20749 {
20750   unformat_input_t *i = vam->input;
20751   vl_api_p2p_ethernet_del_t *mp;
20752   u32 parent_if_index = ~0;
20753   u8 remote_mac[6];
20754   u8 mac_set = 0;
20755   int ret;
20756
20757   clib_memset (remote_mac, 0, sizeof (remote_mac));
20758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20759     {
20760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20761         ;
20762       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20763         ;
20764       else
20765         if (unformat
20766             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20767         mac_set++;
20768       else
20769         {
20770           clib_warning ("parse error '%U'", format_unformat_error, i);
20771           return -99;
20772         }
20773     }
20774
20775   if (parent_if_index == ~0)
20776     {
20777       errmsg ("missing interface name or sw_if_index");
20778       return -99;
20779     }
20780   if (mac_set == 0)
20781     {
20782       errmsg ("missing remote mac address");
20783       return -99;
20784     }
20785
20786   M (P2P_ETHERNET_DEL, mp);
20787   mp->parent_if_index = ntohl (parent_if_index);
20788   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20789
20790   S (mp);
20791   W (ret);
20792   return ret;
20793 }
20794
20795 static int
20796 api_lldp_config (vat_main_t * vam)
20797 {
20798   unformat_input_t *i = vam->input;
20799   vl_api_lldp_config_t *mp;
20800   int tx_hold = 0;
20801   int tx_interval = 0;
20802   u8 *sys_name = NULL;
20803   int ret;
20804
20805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20806     {
20807       if (unformat (i, "system-name %s", &sys_name))
20808         ;
20809       else if (unformat (i, "tx-hold %d", &tx_hold))
20810         ;
20811       else if (unformat (i, "tx-interval %d", &tx_interval))
20812         ;
20813       else
20814         {
20815           clib_warning ("parse error '%U'", format_unformat_error, i);
20816           return -99;
20817         }
20818     }
20819
20820   vec_add1 (sys_name, 0);
20821
20822   M (LLDP_CONFIG, mp);
20823   mp->tx_hold = htonl (tx_hold);
20824   mp->tx_interval = htonl (tx_interval);
20825   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20826   vec_free (sys_name);
20827
20828   S (mp);
20829   W (ret);
20830   return ret;
20831 }
20832
20833 static int
20834 api_sw_interface_set_lldp (vat_main_t * vam)
20835 {
20836   unformat_input_t *i = vam->input;
20837   vl_api_sw_interface_set_lldp_t *mp;
20838   u32 sw_if_index = ~0;
20839   u32 enable = 1;
20840   u8 *port_desc = NULL, *mgmt_oid = NULL;
20841   ip4_address_t ip4_addr;
20842   ip6_address_t ip6_addr;
20843   int ret;
20844
20845   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20846   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20847
20848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20849     {
20850       if (unformat (i, "disable"))
20851         enable = 0;
20852       else
20853         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20854         ;
20855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20856         ;
20857       else if (unformat (i, "port-desc %s", &port_desc))
20858         ;
20859       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20860         ;
20861       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20862         ;
20863       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20864         ;
20865       else
20866         break;
20867     }
20868
20869   if (sw_if_index == ~0)
20870     {
20871       errmsg ("missing interface name or sw_if_index");
20872       return -99;
20873     }
20874
20875   /* Construct the API message */
20876   vec_add1 (port_desc, 0);
20877   vec_add1 (mgmt_oid, 0);
20878   M (SW_INTERFACE_SET_LLDP, mp);
20879   mp->sw_if_index = ntohl (sw_if_index);
20880   mp->enable = enable;
20881   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20882   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20883   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20884   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20885   vec_free (port_desc);
20886   vec_free (mgmt_oid);
20887
20888   S (mp);
20889   W (ret);
20890   return ret;
20891 }
20892
20893 static int
20894 api_tcp_configure_src_addresses (vat_main_t * vam)
20895 {
20896   vl_api_tcp_configure_src_addresses_t *mp;
20897   unformat_input_t *i = vam->input;
20898   ip4_address_t v4first, v4last;
20899   ip6_address_t v6first, v6last;
20900   u8 range_set = 0;
20901   u32 vrf_id = 0;
20902   int ret;
20903
20904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20905     {
20906       if (unformat (i, "%U - %U",
20907                     unformat_ip4_address, &v4first,
20908                     unformat_ip4_address, &v4last))
20909         {
20910           if (range_set)
20911             {
20912               errmsg ("one range per message (range already set)");
20913               return -99;
20914             }
20915           range_set = 1;
20916         }
20917       else if (unformat (i, "%U - %U",
20918                          unformat_ip6_address, &v6first,
20919                          unformat_ip6_address, &v6last))
20920         {
20921           if (range_set)
20922             {
20923               errmsg ("one range per message (range already set)");
20924               return -99;
20925             }
20926           range_set = 2;
20927         }
20928       else if (unformat (i, "vrf %d", &vrf_id))
20929         ;
20930       else
20931         break;
20932     }
20933
20934   if (range_set == 0)
20935     {
20936       errmsg ("address range not set");
20937       return -99;
20938     }
20939
20940   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20941   mp->vrf_id = ntohl (vrf_id);
20942   /* ipv6? */
20943   if (range_set == 2)
20944     {
20945       mp->is_ipv6 = 1;
20946       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20947       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20948     }
20949   else
20950     {
20951       mp->is_ipv6 = 0;
20952       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20953       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20954     }
20955   S (mp);
20956   W (ret);
20957   return ret;
20958 }
20959
20960 static void vl_api_app_namespace_add_del_reply_t_handler
20961   (vl_api_app_namespace_add_del_reply_t * mp)
20962 {
20963   vat_main_t *vam = &vat_main;
20964   i32 retval = ntohl (mp->retval);
20965   if (vam->async_mode)
20966     {
20967       vam->async_errors += (retval < 0);
20968     }
20969   else
20970     {
20971       vam->retval = retval;
20972       if (retval == 0)
20973         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20974       vam->result_ready = 1;
20975     }
20976 }
20977
20978 static void vl_api_app_namespace_add_del_reply_t_handler_json
20979   (vl_api_app_namespace_add_del_reply_t * mp)
20980 {
20981   vat_main_t *vam = &vat_main;
20982   vat_json_node_t node;
20983
20984   vat_json_init_object (&node);
20985   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20986   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20987
20988   vat_json_print (vam->ofp, &node);
20989   vat_json_free (&node);
20990
20991   vam->retval = ntohl (mp->retval);
20992   vam->result_ready = 1;
20993 }
20994
20995 static int
20996 api_app_namespace_add_del (vat_main_t * vam)
20997 {
20998   vl_api_app_namespace_add_del_t *mp;
20999   unformat_input_t *i = vam->input;
21000   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21001   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21002   u64 secret;
21003   int ret;
21004
21005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21006     {
21007       if (unformat (i, "id %_%v%_", &ns_id))
21008         ;
21009       else if (unformat (i, "secret %lu", &secret))
21010         secret_set = 1;
21011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21012         sw_if_index_set = 1;
21013       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21014         ;
21015       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21016         ;
21017       else
21018         break;
21019     }
21020   if (!ns_id || !secret_set || !sw_if_index_set)
21021     {
21022       errmsg ("namespace id, secret and sw_if_index must be set");
21023       return -99;
21024     }
21025   if (vec_len (ns_id) > 64)
21026     {
21027       errmsg ("namespace id too long");
21028       return -99;
21029     }
21030   M (APP_NAMESPACE_ADD_DEL, mp);
21031
21032   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21033   mp->namespace_id_len = vec_len (ns_id);
21034   mp->secret = clib_host_to_net_u64 (secret);
21035   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21036   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21037   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21038   vec_free (ns_id);
21039   S (mp);
21040   W (ret);
21041   return ret;
21042 }
21043
21044 static int
21045 api_sock_init_shm (vat_main_t * vam)
21046 {
21047 #if VPP_API_TEST_BUILTIN == 0
21048   unformat_input_t *i = vam->input;
21049   vl_api_shm_elem_config_t *config = 0;
21050   u64 size = 64 << 20;
21051   int rv;
21052
21053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21054     {
21055       if (unformat (i, "size %U", unformat_memory_size, &size))
21056         ;
21057       else
21058         break;
21059     }
21060
21061   /*
21062    * Canned custom ring allocator config.
21063    * Should probably parse all of this
21064    */
21065   vec_validate (config, 6);
21066   config[0].type = VL_API_VLIB_RING;
21067   config[0].size = 256;
21068   config[0].count = 32;
21069
21070   config[1].type = VL_API_VLIB_RING;
21071   config[1].size = 1024;
21072   config[1].count = 16;
21073
21074   config[2].type = VL_API_VLIB_RING;
21075   config[2].size = 4096;
21076   config[2].count = 2;
21077
21078   config[3].type = VL_API_CLIENT_RING;
21079   config[3].size = 256;
21080   config[3].count = 32;
21081
21082   config[4].type = VL_API_CLIENT_RING;
21083   config[4].size = 1024;
21084   config[4].count = 16;
21085
21086   config[5].type = VL_API_CLIENT_RING;
21087   config[5].size = 4096;
21088   config[5].count = 2;
21089
21090   config[6].type = VL_API_QUEUE;
21091   config[6].count = 128;
21092   config[6].size = sizeof (uword);
21093
21094   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21095   if (!rv)
21096     vam->client_index_invalid = 1;
21097   return rv;
21098 #else
21099   return -99;
21100 #endif
21101 }
21102
21103 static int
21104 api_dns_enable_disable (vat_main_t * vam)
21105 {
21106   unformat_input_t *line_input = vam->input;
21107   vl_api_dns_enable_disable_t *mp;
21108   u8 enable_disable = 1;
21109   int ret;
21110
21111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21112     {
21113       if (unformat (line_input, "disable"))
21114         enable_disable = 0;
21115       if (unformat (line_input, "enable"))
21116         enable_disable = 1;
21117       else
21118         break;
21119     }
21120
21121   /* Construct the API message */
21122   M (DNS_ENABLE_DISABLE, mp);
21123   mp->enable = enable_disable;
21124
21125   /* send it... */
21126   S (mp);
21127   /* Wait for the reply */
21128   W (ret);
21129   return ret;
21130 }
21131
21132 static int
21133 api_dns_resolve_name (vat_main_t * vam)
21134 {
21135   unformat_input_t *line_input = vam->input;
21136   vl_api_dns_resolve_name_t *mp;
21137   u8 *name = 0;
21138   int ret;
21139
21140   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21141     {
21142       if (unformat (line_input, "%s", &name))
21143         ;
21144       else
21145         break;
21146     }
21147
21148   if (vec_len (name) > 127)
21149     {
21150       errmsg ("name too long");
21151       return -99;
21152     }
21153
21154   /* Construct the API message */
21155   M (DNS_RESOLVE_NAME, mp);
21156   memcpy (mp->name, name, vec_len (name));
21157   vec_free (name);
21158
21159   /* send it... */
21160   S (mp);
21161   /* Wait for the reply */
21162   W (ret);
21163   return ret;
21164 }
21165
21166 static int
21167 api_dns_resolve_ip (vat_main_t * vam)
21168 {
21169   unformat_input_t *line_input = vam->input;
21170   vl_api_dns_resolve_ip_t *mp;
21171   int is_ip6 = -1;
21172   ip4_address_t addr4;
21173   ip6_address_t addr6;
21174   int ret;
21175
21176   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21177     {
21178       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21179         is_ip6 = 1;
21180       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21181         is_ip6 = 0;
21182       else
21183         break;
21184     }
21185
21186   if (is_ip6 == -1)
21187     {
21188       errmsg ("missing address");
21189       return -99;
21190     }
21191
21192   /* Construct the API message */
21193   M (DNS_RESOLVE_IP, mp);
21194   mp->is_ip6 = is_ip6;
21195   if (is_ip6)
21196     memcpy (mp->address, &addr6, sizeof (addr6));
21197   else
21198     memcpy (mp->address, &addr4, sizeof (addr4));
21199
21200   /* send it... */
21201   S (mp);
21202   /* Wait for the reply */
21203   W (ret);
21204   return ret;
21205 }
21206
21207 static int
21208 api_dns_name_server_add_del (vat_main_t * vam)
21209 {
21210   unformat_input_t *i = vam->input;
21211   vl_api_dns_name_server_add_del_t *mp;
21212   u8 is_add = 1;
21213   ip6_address_t ip6_server;
21214   ip4_address_t ip4_server;
21215   int ip6_set = 0;
21216   int ip4_set = 0;
21217   int ret = 0;
21218
21219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21220     {
21221       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21222         ip6_set = 1;
21223       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21224         ip4_set = 1;
21225       else if (unformat (i, "del"))
21226         is_add = 0;
21227       else
21228         {
21229           clib_warning ("parse error '%U'", format_unformat_error, i);
21230           return -99;
21231         }
21232     }
21233
21234   if (ip4_set && ip6_set)
21235     {
21236       errmsg ("Only one server address allowed per message");
21237       return -99;
21238     }
21239   if ((ip4_set + ip6_set) == 0)
21240     {
21241       errmsg ("Server address required");
21242       return -99;
21243     }
21244
21245   /* Construct the API message */
21246   M (DNS_NAME_SERVER_ADD_DEL, mp);
21247
21248   if (ip6_set)
21249     {
21250       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21251       mp->is_ip6 = 1;
21252     }
21253   else
21254     {
21255       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21256       mp->is_ip6 = 0;
21257     }
21258
21259   mp->is_add = is_add;
21260
21261   /* send it... */
21262   S (mp);
21263
21264   /* Wait for a reply, return good/bad news  */
21265   W (ret);
21266   return ret;
21267 }
21268
21269 static void
21270 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21271 {
21272   vat_main_t *vam = &vat_main;
21273
21274   if (mp->is_ip4)
21275     {
21276       print (vam->ofp,
21277              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21278              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21279              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21280              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21281              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21282              clib_net_to_host_u32 (mp->action_index), mp->tag);
21283     }
21284   else
21285     {
21286       print (vam->ofp,
21287              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21288              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21289              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21290              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21291              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21292              clib_net_to_host_u32 (mp->action_index), mp->tag);
21293     }
21294 }
21295
21296 static void
21297 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21298                                              mp)
21299 {
21300   vat_main_t *vam = &vat_main;
21301   vat_json_node_t *node = NULL;
21302   struct in6_addr ip6;
21303   struct in_addr ip4;
21304
21305   if (VAT_JSON_ARRAY != vam->json_tree.type)
21306     {
21307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21308       vat_json_init_array (&vam->json_tree);
21309     }
21310   node = vat_json_array_add (&vam->json_tree);
21311   vat_json_init_object (node);
21312
21313   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21314   vat_json_object_add_uint (node, "appns_index",
21315                             clib_net_to_host_u32 (mp->appns_index));
21316   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21317   vat_json_object_add_uint (node, "scope", mp->scope);
21318   vat_json_object_add_uint (node, "action_index",
21319                             clib_net_to_host_u32 (mp->action_index));
21320   vat_json_object_add_uint (node, "lcl_port",
21321                             clib_net_to_host_u16 (mp->lcl_port));
21322   vat_json_object_add_uint (node, "rmt_port",
21323                             clib_net_to_host_u16 (mp->rmt_port));
21324   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21325   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21326   vat_json_object_add_string_copy (node, "tag", mp->tag);
21327   if (mp->is_ip4)
21328     {
21329       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21330       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21331       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21332       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21333     }
21334   else
21335     {
21336       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21337       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21338       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21339       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21340     }
21341 }
21342
21343 static int
21344 api_session_rule_add_del (vat_main_t * vam)
21345 {
21346   vl_api_session_rule_add_del_t *mp;
21347   unformat_input_t *i = vam->input;
21348   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21349   u32 appns_index = 0, scope = 0;
21350   ip4_address_t lcl_ip4, rmt_ip4;
21351   ip6_address_t lcl_ip6, rmt_ip6;
21352   u8 is_ip4 = 1, conn_set = 0;
21353   u8 is_add = 1, *tag = 0;
21354   int ret;
21355
21356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21357     {
21358       if (unformat (i, "del"))
21359         is_add = 0;
21360       else if (unformat (i, "add"))
21361         ;
21362       else if (unformat (i, "proto tcp"))
21363         proto = 0;
21364       else if (unformat (i, "proto udp"))
21365         proto = 1;
21366       else if (unformat (i, "appns %d", &appns_index))
21367         ;
21368       else if (unformat (i, "scope %d", &scope))
21369         ;
21370       else if (unformat (i, "tag %_%v%_", &tag))
21371         ;
21372       else
21373         if (unformat
21374             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21375              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21376              &rmt_port))
21377         {
21378           is_ip4 = 1;
21379           conn_set = 1;
21380         }
21381       else
21382         if (unformat
21383             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21384              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21385              &rmt_port))
21386         {
21387           is_ip4 = 0;
21388           conn_set = 1;
21389         }
21390       else if (unformat (i, "action %d", &action))
21391         ;
21392       else
21393         break;
21394     }
21395   if (proto == ~0 || !conn_set || action == ~0)
21396     {
21397       errmsg ("transport proto, connection and action must be set");
21398       return -99;
21399     }
21400
21401   if (scope > 3)
21402     {
21403       errmsg ("scope should be 0-3");
21404       return -99;
21405     }
21406
21407   M (SESSION_RULE_ADD_DEL, mp);
21408
21409   mp->is_ip4 = is_ip4;
21410   mp->transport_proto = proto;
21411   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21412   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21413   mp->lcl_plen = lcl_plen;
21414   mp->rmt_plen = rmt_plen;
21415   mp->action_index = clib_host_to_net_u32 (action);
21416   mp->appns_index = clib_host_to_net_u32 (appns_index);
21417   mp->scope = scope;
21418   mp->is_add = is_add;
21419   if (is_ip4)
21420     {
21421       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21422       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21423     }
21424   else
21425     {
21426       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21427       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21428     }
21429   if (tag)
21430     {
21431       clib_memcpy (mp->tag, tag, vec_len (tag));
21432       vec_free (tag);
21433     }
21434
21435   S (mp);
21436   W (ret);
21437   return ret;
21438 }
21439
21440 static int
21441 api_session_rules_dump (vat_main_t * vam)
21442 {
21443   vl_api_session_rules_dump_t *mp;
21444   vl_api_control_ping_t *mp_ping;
21445   int ret;
21446
21447   if (!vam->json_output)
21448     {
21449       print (vam->ofp, "%=20s", "Session Rules");
21450     }
21451
21452   M (SESSION_RULES_DUMP, mp);
21453   /* send it... */
21454   S (mp);
21455
21456   /* Use a control ping for synchronization */
21457   MPING (CONTROL_PING, mp_ping);
21458   S (mp_ping);
21459
21460   /* Wait for a reply... */
21461   W (ret);
21462   return ret;
21463 }
21464
21465 static int
21466 api_ip_container_proxy_add_del (vat_main_t * vam)
21467 {
21468   vl_api_ip_container_proxy_add_del_t *mp;
21469   unformat_input_t *i = vam->input;
21470   u32 sw_if_index = ~0;
21471   vl_api_prefix_t pfx = { };
21472   u8 is_add = 1;
21473   int ret;
21474
21475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21476     {
21477       if (unformat (i, "del"))
21478         is_add = 0;
21479       else if (unformat (i, "add"))
21480         ;
21481       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21482         ;
21483       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21484         ;
21485       else
21486         break;
21487     }
21488   if (sw_if_index == ~0 || pfx.address_length == 0)
21489     {
21490       errmsg ("address and sw_if_index must be set");
21491       return -99;
21492     }
21493
21494   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21495
21496   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21497   mp->is_add = is_add;
21498   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21499
21500   S (mp);
21501   W (ret);
21502   return ret;
21503 }
21504
21505 static int
21506 api_qos_record_enable_disable (vat_main_t * vam)
21507 {
21508   unformat_input_t *i = vam->input;
21509   vl_api_qos_record_enable_disable_t *mp;
21510   u32 sw_if_index, qs = 0xff;
21511   u8 sw_if_index_set = 0;
21512   u8 enable = 1;
21513   int ret;
21514
21515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21516     {
21517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21518         sw_if_index_set = 1;
21519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21520         sw_if_index_set = 1;
21521       else if (unformat (i, "%U", unformat_qos_source, &qs))
21522         ;
21523       else if (unformat (i, "disable"))
21524         enable = 0;
21525       else
21526         {
21527           clib_warning ("parse error '%U'", format_unformat_error, i);
21528           return -99;
21529         }
21530     }
21531
21532   if (sw_if_index_set == 0)
21533     {
21534       errmsg ("missing interface name or sw_if_index");
21535       return -99;
21536     }
21537   if (qs == 0xff)
21538     {
21539       errmsg ("input location must be specified");
21540       return -99;
21541     }
21542
21543   M (QOS_RECORD_ENABLE_DISABLE, mp);
21544
21545   mp->sw_if_index = ntohl (sw_if_index);
21546   mp->input_source = qs;
21547   mp->enable = enable;
21548
21549   S (mp);
21550   W (ret);
21551   return ret;
21552 }
21553
21554
21555 static int
21556 q_or_quit (vat_main_t * vam)
21557 {
21558 #if VPP_API_TEST_BUILTIN == 0
21559   longjmp (vam->jump_buf, 1);
21560 #endif
21561   return 0;                     /* not so much */
21562 }
21563
21564 static int
21565 q (vat_main_t * vam)
21566 {
21567   return q_or_quit (vam);
21568 }
21569
21570 static int
21571 quit (vat_main_t * vam)
21572 {
21573   return q_or_quit (vam);
21574 }
21575
21576 static int
21577 comment (vat_main_t * vam)
21578 {
21579   return 0;
21580 }
21581
21582 static int
21583 statseg (vat_main_t * vam)
21584 {
21585   ssvm_private_t *ssvmp = &vam->stat_segment;
21586   ssvm_shared_header_t *shared_header = ssvmp->sh;
21587   vlib_counter_t **counters;
21588   u64 thread0_index1_packets;
21589   u64 thread0_index1_bytes;
21590   f64 vector_rate, input_rate;
21591   uword *p;
21592
21593   uword *counter_vector_by_name;
21594   if (vam->stat_segment_lockp == 0)
21595     {
21596       errmsg ("Stat segment not mapped...");
21597       return -99;
21598     }
21599
21600   /* look up "/if/rx for sw_if_index 1 as a test */
21601
21602   clib_spinlock_lock (vam->stat_segment_lockp);
21603
21604   counter_vector_by_name = (uword *) shared_header->opaque[1];
21605
21606   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21607   if (p == 0)
21608     {
21609       clib_spinlock_unlock (vam->stat_segment_lockp);
21610       errmsg ("/if/tx not found?");
21611       return -99;
21612     }
21613
21614   /* Fish per-thread vector of combined counters from shared memory */
21615   counters = (vlib_counter_t **) p[0];
21616
21617   if (vec_len (counters[0]) < 2)
21618     {
21619       clib_spinlock_unlock (vam->stat_segment_lockp);
21620       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21621       return -99;
21622     }
21623
21624   /* Read thread 0 sw_if_index 1 counter */
21625   thread0_index1_packets = counters[0][1].packets;
21626   thread0_index1_bytes = counters[0][1].bytes;
21627
21628   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21629   if (p == 0)
21630     {
21631       clib_spinlock_unlock (vam->stat_segment_lockp);
21632       errmsg ("vector_rate not found?");
21633       return -99;
21634     }
21635
21636   vector_rate = *(f64 *) (p[0]);
21637   p = hash_get_mem (counter_vector_by_name, "input_rate");
21638   if (p == 0)
21639     {
21640       clib_spinlock_unlock (vam->stat_segment_lockp);
21641       errmsg ("input_rate not found?");
21642       return -99;
21643     }
21644   input_rate = *(f64 *) (p[0]);
21645
21646   clib_spinlock_unlock (vam->stat_segment_lockp);
21647
21648   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21649          vector_rate, input_rate);
21650   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21651          thread0_index1_packets, thread0_index1_bytes);
21652
21653   return 0;
21654 }
21655
21656 static int
21657 cmd_cmp (void *a1, void *a2)
21658 {
21659   u8 **c1 = a1;
21660   u8 **c2 = a2;
21661
21662   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21663 }
21664
21665 static int
21666 help (vat_main_t * vam)
21667 {
21668   u8 **cmds = 0;
21669   u8 *name = 0;
21670   hash_pair_t *p;
21671   unformat_input_t *i = vam->input;
21672   int j;
21673
21674   if (unformat (i, "%s", &name))
21675     {
21676       uword *hs;
21677
21678       vec_add1 (name, 0);
21679
21680       hs = hash_get_mem (vam->help_by_name, name);
21681       if (hs)
21682         print (vam->ofp, "usage: %s %s", name, hs[0]);
21683       else
21684         print (vam->ofp, "No such msg / command '%s'", name);
21685       vec_free (name);
21686       return 0;
21687     }
21688
21689   print (vam->ofp, "Help is available for the following:");
21690
21691     /* *INDENT-OFF* */
21692     hash_foreach_pair (p, vam->function_by_name,
21693     ({
21694       vec_add1 (cmds, (u8 *)(p->key));
21695     }));
21696     /* *INDENT-ON* */
21697
21698   vec_sort_with_function (cmds, cmd_cmp);
21699
21700   for (j = 0; j < vec_len (cmds); j++)
21701     print (vam->ofp, "%s", cmds[j]);
21702
21703   vec_free (cmds);
21704   return 0;
21705 }
21706
21707 static int
21708 set (vat_main_t * vam)
21709 {
21710   u8 *name = 0, *value = 0;
21711   unformat_input_t *i = vam->input;
21712
21713   if (unformat (i, "%s", &name))
21714     {
21715       /* The input buffer is a vector, not a string. */
21716       value = vec_dup (i->buffer);
21717       vec_delete (value, i->index, 0);
21718       /* Almost certainly has a trailing newline */
21719       if (value[vec_len (value) - 1] == '\n')
21720         value[vec_len (value) - 1] = 0;
21721       /* Make sure it's a proper string, one way or the other */
21722       vec_add1 (value, 0);
21723       (void) clib_macro_set_value (&vam->macro_main,
21724                                    (char *) name, (char *) value);
21725     }
21726   else
21727     errmsg ("usage: set <name> <value>");
21728
21729   vec_free (name);
21730   vec_free (value);
21731   return 0;
21732 }
21733
21734 static int
21735 unset (vat_main_t * vam)
21736 {
21737   u8 *name = 0;
21738
21739   if (unformat (vam->input, "%s", &name))
21740     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21741       errmsg ("unset: %s wasn't set", name);
21742   vec_free (name);
21743   return 0;
21744 }
21745
21746 typedef struct
21747 {
21748   u8 *name;
21749   u8 *value;
21750 } macro_sort_t;
21751
21752
21753 static int
21754 macro_sort_cmp (void *a1, void *a2)
21755 {
21756   macro_sort_t *s1 = a1;
21757   macro_sort_t *s2 = a2;
21758
21759   return strcmp ((char *) (s1->name), (char *) (s2->name));
21760 }
21761
21762 static int
21763 dump_macro_table (vat_main_t * vam)
21764 {
21765   macro_sort_t *sort_me = 0, *sm;
21766   int i;
21767   hash_pair_t *p;
21768
21769     /* *INDENT-OFF* */
21770     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21771     ({
21772       vec_add2 (sort_me, sm, 1);
21773       sm->name = (u8 *)(p->key);
21774       sm->value = (u8 *) (p->value[0]);
21775     }));
21776     /* *INDENT-ON* */
21777
21778   vec_sort_with_function (sort_me, macro_sort_cmp);
21779
21780   if (vec_len (sort_me))
21781     print (vam->ofp, "%-15s%s", "Name", "Value");
21782   else
21783     print (vam->ofp, "The macro table is empty...");
21784
21785   for (i = 0; i < vec_len (sort_me); i++)
21786     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21787   return 0;
21788 }
21789
21790 static int
21791 dump_node_table (vat_main_t * vam)
21792 {
21793   int i, j;
21794   vlib_node_t *node, *next_node;
21795
21796   if (vec_len (vam->graph_nodes) == 0)
21797     {
21798       print (vam->ofp, "Node table empty, issue get_node_graph...");
21799       return 0;
21800     }
21801
21802   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21803     {
21804       node = vam->graph_nodes[0][i];
21805       print (vam->ofp, "[%d] %s", i, node->name);
21806       for (j = 0; j < vec_len (node->next_nodes); j++)
21807         {
21808           if (node->next_nodes[j] != ~0)
21809             {
21810               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21811               print (vam->ofp, "  [%d] %s", j, next_node->name);
21812             }
21813         }
21814     }
21815   return 0;
21816 }
21817
21818 static int
21819 value_sort_cmp (void *a1, void *a2)
21820 {
21821   name_sort_t *n1 = a1;
21822   name_sort_t *n2 = a2;
21823
21824   if (n1->value < n2->value)
21825     return -1;
21826   if (n1->value > n2->value)
21827     return 1;
21828   return 0;
21829 }
21830
21831
21832 static int
21833 dump_msg_api_table (vat_main_t * vam)
21834 {
21835   api_main_t *am = &api_main;
21836   name_sort_t *nses = 0, *ns;
21837   hash_pair_t *hp;
21838   int i;
21839
21840   /* *INDENT-OFF* */
21841   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21842   ({
21843     vec_add2 (nses, ns, 1);
21844     ns->name = (u8 *)(hp->key);
21845     ns->value = (u32) hp->value[0];
21846   }));
21847   /* *INDENT-ON* */
21848
21849   vec_sort_with_function (nses, value_sort_cmp);
21850
21851   for (i = 0; i < vec_len (nses); i++)
21852     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21853   vec_free (nses);
21854   return 0;
21855 }
21856
21857 static int
21858 get_msg_id (vat_main_t * vam)
21859 {
21860   u8 *name_and_crc;
21861   u32 message_index;
21862
21863   if (unformat (vam->input, "%s", &name_and_crc))
21864     {
21865       message_index = vl_msg_api_get_msg_index (name_and_crc);
21866       if (message_index == ~0)
21867         {
21868           print (vam->ofp, " '%s' not found", name_and_crc);
21869           return 0;
21870         }
21871       print (vam->ofp, " '%s' has message index %d",
21872              name_and_crc, message_index);
21873       return 0;
21874     }
21875   errmsg ("name_and_crc required...");
21876   return 0;
21877 }
21878
21879 static int
21880 search_node_table (vat_main_t * vam)
21881 {
21882   unformat_input_t *line_input = vam->input;
21883   u8 *node_to_find;
21884   int j;
21885   vlib_node_t *node, *next_node;
21886   uword *p;
21887
21888   if (vam->graph_node_index_by_name == 0)
21889     {
21890       print (vam->ofp, "Node table empty, issue get_node_graph...");
21891       return 0;
21892     }
21893
21894   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21895     {
21896       if (unformat (line_input, "%s", &node_to_find))
21897         {
21898           vec_add1 (node_to_find, 0);
21899           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21900           if (p == 0)
21901             {
21902               print (vam->ofp, "%s not found...", node_to_find);
21903               goto out;
21904             }
21905           node = vam->graph_nodes[0][p[0]];
21906           print (vam->ofp, "[%d] %s", p[0], node->name);
21907           for (j = 0; j < vec_len (node->next_nodes); j++)
21908             {
21909               if (node->next_nodes[j] != ~0)
21910                 {
21911                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21912                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21913                 }
21914             }
21915         }
21916
21917       else
21918         {
21919           clib_warning ("parse error '%U'", format_unformat_error,
21920                         line_input);
21921           return -99;
21922         }
21923
21924     out:
21925       vec_free (node_to_find);
21926
21927     }
21928
21929   return 0;
21930 }
21931
21932
21933 static int
21934 script (vat_main_t * vam)
21935 {
21936 #if (VPP_API_TEST_BUILTIN==0)
21937   u8 *s = 0;
21938   char *save_current_file;
21939   unformat_input_t save_input;
21940   jmp_buf save_jump_buf;
21941   u32 save_line_number;
21942
21943   FILE *new_fp, *save_ifp;
21944
21945   if (unformat (vam->input, "%s", &s))
21946     {
21947       new_fp = fopen ((char *) s, "r");
21948       if (new_fp == 0)
21949         {
21950           errmsg ("Couldn't open script file %s", s);
21951           vec_free (s);
21952           return -99;
21953         }
21954     }
21955   else
21956     {
21957       errmsg ("Missing script name");
21958       return -99;
21959     }
21960
21961   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21962   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21963   save_ifp = vam->ifp;
21964   save_line_number = vam->input_line_number;
21965   save_current_file = (char *) vam->current_file;
21966
21967   vam->input_line_number = 0;
21968   vam->ifp = new_fp;
21969   vam->current_file = s;
21970   do_one_file (vam);
21971
21972   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21973   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21974   vam->ifp = save_ifp;
21975   vam->input_line_number = save_line_number;
21976   vam->current_file = (u8 *) save_current_file;
21977   vec_free (s);
21978
21979   return 0;
21980 #else
21981   clib_warning ("use the exec command...");
21982   return -99;
21983 #endif
21984 }
21985
21986 static int
21987 echo (vat_main_t * vam)
21988 {
21989   print (vam->ofp, "%v", vam->input->buffer);
21990   return 0;
21991 }
21992
21993 /* List of API message constructors, CLI names map to api_xxx */
21994 #define foreach_vpe_api_msg                                             \
21995 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21996 _(sw_interface_dump,"")                                                 \
21997 _(sw_interface_set_flags,                                               \
21998   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21999 _(sw_interface_add_del_address,                                         \
22000   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22001 _(sw_interface_set_rx_mode,                                             \
22002   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22003 _(sw_interface_set_rx_placement,                                        \
22004   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22005 _(sw_interface_rx_placement_dump,                                       \
22006   "[<intfc> | sw_if_index <id>]")                                         \
22007 _(sw_interface_set_table,                                               \
22008   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22009 _(sw_interface_set_mpls_enable,                                         \
22010   "<intfc> | sw_if_index [disable | dis]")                              \
22011 _(sw_interface_set_vpath,                                               \
22012   "<intfc> | sw_if_index <id> enable | disable")                        \
22013 _(sw_interface_set_vxlan_bypass,                                        \
22014   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22015 _(sw_interface_set_geneve_bypass,                                       \
22016   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22017 _(sw_interface_set_l2_xconnect,                                         \
22018   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22019   "enable | disable")                                                   \
22020 _(sw_interface_set_l2_bridge,                                           \
22021   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22022   "[shg <split-horizon-group>] [bvi]\n"                                 \
22023   "enable | disable")                                                   \
22024 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22025 _(bridge_domain_add_del,                                                \
22026   "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") \
22027 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22028 _(l2fib_add_del,                                                        \
22029   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22030 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22031 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22032 _(l2_flags,                                                             \
22033   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22034 _(bridge_flags,                                                         \
22035   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22036 _(tap_create_v2,                                                        \
22037   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22038 _(tap_delete_v2,                                                        \
22039   "<vpp-if-name> | sw_if_index <id>")                                   \
22040 _(sw_interface_tap_v2_dump, "")                                         \
22041 _(virtio_pci_create,                                                    \
22042   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22043 _(virtio_pci_delete,                                                    \
22044   "<vpp-if-name> | sw_if_index <id>")                                   \
22045 _(sw_interface_virtio_pci_dump, "")                                     \
22046 _(bond_create,                                                          \
22047   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22048   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22049   "[id <if-id>]")                                                       \
22050 _(bond_delete,                                                          \
22051   "<vpp-if-name> | sw_if_index <id>")                                   \
22052 _(bond_enslave,                                                         \
22053   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22054 _(bond_detach_slave,                                                    \
22055   "sw_if_index <n>")                                                    \
22056 _(sw_interface_bond_dump, "")                                           \
22057 _(sw_interface_slave_dump,                                              \
22058   "<vpp-if-name> | sw_if_index <id>")                                   \
22059 _(ip_table_add_del,                                                     \
22060   "table <n> [ipv6] [add | del]\n")                                     \
22061 _(ip_route_add_del,                                                     \
22062   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22063   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22064   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22065   "[multipath] [count <n>] [del]")                                      \
22066 _(ip_mroute_add_del,                                                    \
22067   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22068   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22069 _(mpls_table_add_del,                                                   \
22070   "table <n> [add | del]\n")                                            \
22071 _(mpls_route_add_del,                                                   \
22072   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22073   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22074   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22075   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22076   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22077   "[count <n>] [del]")                                                  \
22078 _(mpls_ip_bind_unbind,                                                  \
22079   "<label> <addr/len>")                                                 \
22080 _(mpls_tunnel_add_del,                                                  \
22081   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22082   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22083   "[l2-only]  [out-label <n>]")                                         \
22084 _(sr_mpls_policy_add,                                                   \
22085   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22086 _(sr_mpls_policy_del,                                                   \
22087   "bsid <id>")                                                          \
22088 _(bier_table_add_del,                                                   \
22089   "<label> <sub-domain> <set> <bsl> [del]")                             \
22090 _(bier_route_add_del,                                                   \
22091   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22092   "[<intfc> | sw_if_index <id>]"                                        \
22093   "[weight <n>] [del] [multipath]")                                     \
22094 _(proxy_arp_add_del,                                                    \
22095   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22096 _(proxy_arp_intfc_enable_disable,                                       \
22097   "<intfc> | sw_if_index <id> enable | disable")                        \
22098 _(sw_interface_set_unnumbered,                                          \
22099   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22100 _(ip_neighbor_add_del,                                                  \
22101   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22102   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22103 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22104 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22105   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22106   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22107   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22108 _(reset_fib, "vrf <n> [ipv6]")                                          \
22109 _(dhcp_proxy_config,                                                    \
22110   "svr <v46-address> src <v46-address>\n"                               \
22111    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22112 _(dhcp_proxy_set_vss,                                                   \
22113   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22114 _(dhcp_proxy_dump, "ip6")                                               \
22115 _(dhcp_client_config,                                                   \
22116   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22117 _(set_ip_flow_hash,                                                     \
22118   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22119 _(sw_interface_ip6_enable_disable,                                      \
22120   "<intfc> | sw_if_index <id> enable | disable")                        \
22121 _(ip6nd_proxy_add_del,                                                  \
22122   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22123 _(ip6nd_proxy_dump, "")                                                 \
22124 _(sw_interface_ip6nd_ra_prefix,                                         \
22125   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22126   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22127   "[nolink] [isno]")                                                    \
22128 _(sw_interface_ip6nd_ra_config,                                         \
22129   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22130   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22131   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22132 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22133 _(l2_patch_add_del,                                                     \
22134   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22135   "enable | disable")                                                   \
22136 _(sr_localsid_add_del,                                                  \
22137   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22138   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22139 _(classify_add_del_table,                                               \
22140   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22141   " [del] [del-chain] mask <mask-value>\n"                              \
22142   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22143   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22144 _(classify_add_del_session,                                             \
22145   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22146   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22147   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22148   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22149 _(classify_set_interface_ip_table,                                      \
22150   "<intfc> | sw_if_index <nn> table <nn>")                              \
22151 _(classify_set_interface_l2_tables,                                     \
22152   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22153   "  [other-table <nn>]")                                               \
22154 _(get_node_index, "node <node-name")                                    \
22155 _(add_node_next, "node <node-name> next <next-node-name>")              \
22156 _(l2tpv3_create_tunnel,                                                 \
22157   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22158   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22159   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22160 _(l2tpv3_set_tunnel_cookies,                                            \
22161   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22162   "[new_remote_cookie <nn>]\n")                                         \
22163 _(l2tpv3_interface_enable_disable,                                      \
22164   "<intfc> | sw_if_index <nn> enable | disable")                        \
22165 _(l2tpv3_set_lookup_key,                                                \
22166   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22167 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22168 _(vxlan_offload_rx,                                                     \
22169   "hw { <interface name> | hw_if_index <nn>} "                          \
22170   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22171 _(vxlan_add_del_tunnel,                                                 \
22172   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22173   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22174   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22175 _(geneve_add_del_tunnel,                                                \
22176   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22177   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22178   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22179 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22180 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22181 _(gre_tunnel_add_del,                                                   \
22182   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22183   "[teb | erspan <session-id>] [del]")                                  \
22184 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22185 _(l2_fib_clear_table, "")                                               \
22186 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22187 _(l2_interface_vlan_tag_rewrite,                                        \
22188   "<intfc> | sw_if_index <nn> \n"                                       \
22189   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22190   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22191 _(create_vhost_user_if,                                                 \
22192         "socket <filename> [server] [renumber <dev_instance>] "         \
22193         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22194         "[mac <mac_address>]")                                          \
22195 _(modify_vhost_user_if,                                                 \
22196         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22197         "[server] [renumber <dev_instance>]")                           \
22198 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22199 _(sw_interface_vhost_user_dump, "")                                     \
22200 _(show_version, "")                                                     \
22201 _(show_threads, "")                                                     \
22202 _(vxlan_gpe_add_del_tunnel,                                             \
22203   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22204   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22205   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22206   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22207 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22208 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22209 _(interface_name_renumber,                                              \
22210   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22211 _(input_acl_set_interface,                                              \
22212   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22213   "  [l2-table <nn>] [del]")                                            \
22214 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22215 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22216   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22217 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22218 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22219 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22220 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22221 _(ip_dump, "ipv4 | ipv6")                                               \
22222 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22223 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22224   "  spid_id <n> ")                                                     \
22225 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22226   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22227   "  integ_alg <alg> integ_key <hex>")                                  \
22228 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22229   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22230   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22231   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22232 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22233   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22234   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22235   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22236   "  [instance <n>]")     \
22237 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22238 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22239 _(delete_loopback,"sw_if_index <nn>")                                   \
22240 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22241 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22242 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22243 _(want_interface_events,  "enable|disable")                             \
22244 _(get_first_msg_id, "client <name>")                                    \
22245 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22246 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22247   "fib-id <nn> [ip4][ip6][default]")                                    \
22248 _(get_node_graph, " ")                                                  \
22249 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22250 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22251 _(ioam_disable, "")                                                     \
22252 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22253                             " sw_if_index <sw_if_index> p <priority> "  \
22254                             "w <weight>] [del]")                        \
22255 _(one_add_del_locator, "locator-set <locator_name> "                    \
22256                         "iface <intf> | sw_if_index <sw_if_index> "     \
22257                         "p <priority> w <weight> [del]")                \
22258 _(one_add_del_local_eid,"vni <vni> eid "                                \
22259                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22260                          "locator-set <locator_name> [del]"             \
22261                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22262 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22263 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22264 _(one_enable_disable, "enable|disable")                                 \
22265 _(one_map_register_enable_disable, "enable|disable")                    \
22266 _(one_map_register_fallback_threshold, "<value>")                       \
22267 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22268 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22269                                "[seid <seid>] "                         \
22270                                "rloc <locator> p <prio> "               \
22271                                "w <weight> [rloc <loc> ... ] "          \
22272                                "action <action> [del-all]")             \
22273 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22274                           "<local-eid>")                                \
22275 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22276 _(one_use_petr, "ip-address> | disable")                                \
22277 _(one_map_request_mode, "src-dst|dst-only")                             \
22278 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22279 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22280 _(one_locator_set_dump, "[local | remote]")                             \
22281 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22282 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22283                        "[local] | [remote]")                            \
22284 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22285 _(one_ndp_bd_get, "")                                                   \
22286 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22287 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22288 _(one_l2_arp_bd_get, "")                                                \
22289 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22290 _(one_stats_enable_disable, "enable|disable")                           \
22291 _(show_one_stats_enable_disable, "")                                    \
22292 _(one_eid_table_vni_dump, "")                                           \
22293 _(one_eid_table_map_dump, "l2|l3")                                      \
22294 _(one_map_resolver_dump, "")                                            \
22295 _(one_map_server_dump, "")                                              \
22296 _(one_adjacencies_get, "vni <vni>")                                     \
22297 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22298 _(show_one_rloc_probe_state, "")                                        \
22299 _(show_one_map_register_state, "")                                      \
22300 _(show_one_status, "")                                                  \
22301 _(one_stats_dump, "")                                                   \
22302 _(one_stats_flush, "")                                                  \
22303 _(one_get_map_request_itr_rlocs, "")                                    \
22304 _(one_map_register_set_ttl, "<ttl>")                                    \
22305 _(one_set_transport_protocol, "udp|api")                                \
22306 _(one_get_transport_protocol, "")                                       \
22307 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22308 _(one_show_xtr_mode, "")                                                \
22309 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22310 _(one_show_pitr_mode, "")                                               \
22311 _(one_enable_disable_petr_mode, "enable|disable")                       \
22312 _(one_show_petr_mode, "")                                               \
22313 _(show_one_nsh_mapping, "")                                             \
22314 _(show_one_pitr, "")                                                    \
22315 _(show_one_use_petr, "")                                                \
22316 _(show_one_map_request_mode, "")                                        \
22317 _(show_one_map_register_ttl, "")                                        \
22318 _(show_one_map_register_fallback_threshold, "")                         \
22319 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22320                             " sw_if_index <sw_if_index> p <priority> "  \
22321                             "w <weight>] [del]")                        \
22322 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22323                         "iface <intf> | sw_if_index <sw_if_index> "     \
22324                         "p <priority> w <weight> [del]")                \
22325 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22326                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22327                          "locator-set <locator_name> [del]"             \
22328                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22329 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22330 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22331 _(lisp_enable_disable, "enable|disable")                                \
22332 _(lisp_map_register_enable_disable, "enable|disable")                   \
22333 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22334 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22335                                "[seid <seid>] "                         \
22336                                "rloc <locator> p <prio> "               \
22337                                "w <weight> [rloc <loc> ... ] "          \
22338                                "action <action> [del-all]")             \
22339 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22340                           "<local-eid>")                                \
22341 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22342 _(lisp_use_petr, "<ip-address> | disable")                              \
22343 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22344 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22345 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22346 _(lisp_locator_set_dump, "[local | remote]")                            \
22347 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22348 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22349                        "[local] | [remote]")                            \
22350 _(lisp_eid_table_vni_dump, "")                                          \
22351 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22352 _(lisp_map_resolver_dump, "")                                           \
22353 _(lisp_map_server_dump, "")                                             \
22354 _(lisp_adjacencies_get, "vni <vni>")                                    \
22355 _(gpe_fwd_entry_vnis_get, "")                                           \
22356 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22357 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22358                                 "[table <table-id>]")                   \
22359 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22360 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22361 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22362 _(gpe_get_encap_mode, "")                                               \
22363 _(lisp_gpe_add_del_iface, "up|down")                                    \
22364 _(lisp_gpe_enable_disable, "enable|disable")                            \
22365 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22366   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22367 _(show_lisp_rloc_probe_state, "")                                       \
22368 _(show_lisp_map_register_state, "")                                     \
22369 _(show_lisp_status, "")                                                 \
22370 _(lisp_get_map_request_itr_rlocs, "")                                   \
22371 _(show_lisp_pitr, "")                                                   \
22372 _(show_lisp_use_petr, "")                                               \
22373 _(show_lisp_map_request_mode, "")                                       \
22374 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22375 _(af_packet_delete, "name <host interface name>")                       \
22376 _(af_packet_dump, "")                                                   \
22377 _(policer_add_del, "name <policer name> <params> [del]")                \
22378 _(policer_dump, "[name <policer name>]")                                \
22379 _(policer_classify_set_interface,                                       \
22380   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22381   "  [l2-table <nn>] [del]")                                            \
22382 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22383 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22384     "[master|slave]")                                                   \
22385 _(netmap_delete, "name <interface name>")                               \
22386 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22387 _(mpls_table_dump, "")                                                  \
22388 _(mpls_route_dump, "table-id <ID>")                                     \
22389 _(classify_table_ids, "")                                               \
22390 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22391 _(classify_table_info, "table_id <nn>")                                 \
22392 _(classify_session_dump, "table_id <nn>")                               \
22393 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22394     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22395     "[template_interval <nn>] [udp_checksum]")                          \
22396 _(ipfix_exporter_dump, "")                                              \
22397 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22398 _(ipfix_classify_stream_dump, "")                                       \
22399 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22400 _(ipfix_classify_table_dump, "")                                        \
22401 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22402 _(sw_interface_span_dump, "[l2]")                                           \
22403 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22404 _(pg_create_interface, "if_id <nn>")                                    \
22405 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22406 _(pg_enable_disable, "[stream <id>] disable")                           \
22407 _(ip_source_and_port_range_check_add_del,                               \
22408   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22409 _(ip_source_and_port_range_check_interface_add_del,                     \
22410   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22411   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22412 _(ipsec_gre_tunnel_add_del,                                             \
22413   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22414 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22415 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22416 _(l2_interface_pbb_tag_rewrite,                                         \
22417   "<intfc> | sw_if_index <nn> \n"                                       \
22418   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22419   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22420 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22421 _(flow_classify_set_interface,                                          \
22422   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22423 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22424 _(ip_table_dump, "")                                                    \
22425 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22426 _(ip_mtable_dump, "")                                                   \
22427 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22428 _(feature_enable_disable, "arc_name <arc_name> "                        \
22429   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22430 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22431 "[disable]")                                                            \
22432 _(l2_xconnect_dump, "")                                                 \
22433 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22434 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22435 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22436 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22437 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22438 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22439 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22440   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22441 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22442 _(sock_init_shm, "size <nnn>")                                          \
22443 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22444 _(dns_enable_disable, "[enable][disable]")                              \
22445 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22446 _(dns_resolve_name, "<hostname>")                                       \
22447 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22448 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22449 _(dns_resolve_name, "<hostname>")                                       \
22450 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22451   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22452 _(session_rules_dump, "")                                               \
22453 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22454 _(output_acl_set_interface,                                             \
22455   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22456   "  [l2-table <nn>] [del]")                                            \
22457 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22458
22459 /* List of command functions, CLI names map directly to functions */
22460 #define foreach_cli_function                                    \
22461 _(comment, "usage: comment <ignore-rest-of-line>")              \
22462 _(dump_interface_table, "usage: dump_interface_table")          \
22463 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22464 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22465 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22466 _(dump_macro_table, "usage: dump_macro_table ")                 \
22467 _(dump_node_table, "usage: dump_node_table")                    \
22468 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22469 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22470 _(echo, "usage: echo <message>")                                \
22471 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22472 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22473 _(help, "usage: help")                                          \
22474 _(q, "usage: quit")                                             \
22475 _(quit, "usage: quit")                                          \
22476 _(search_node_table, "usage: search_node_table <name>...")      \
22477 _(set, "usage: set <variable-name> <value>")                    \
22478 _(script, "usage: script <file-name>")                          \
22479 _(statseg, "usage: statseg")                                    \
22480 _(unset, "usage: unset <variable-name>")
22481
22482 #define _(N,n)                                  \
22483     static void vl_api_##n##_t_handler_uni      \
22484     (vl_api_##n##_t * mp)                       \
22485     {                                           \
22486         vat_main_t * vam = &vat_main;           \
22487         if (vam->json_output) {                 \
22488             vl_api_##n##_t_handler_json(mp);    \
22489         } else {                                \
22490             vl_api_##n##_t_handler(mp);         \
22491         }                                       \
22492     }
22493 foreach_vpe_api_reply_msg;
22494 #if VPP_API_TEST_BUILTIN == 0
22495 foreach_standalone_reply_msg;
22496 #endif
22497 #undef _
22498
22499 void
22500 vat_api_hookup (vat_main_t * vam)
22501 {
22502 #define _(N,n)                                                  \
22503     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22504                            vl_api_##n##_t_handler_uni,          \
22505                            vl_noop_handler,                     \
22506                            vl_api_##n##_t_endian,               \
22507                            vl_api_##n##_t_print,                \
22508                            sizeof(vl_api_##n##_t), 1);
22509   foreach_vpe_api_reply_msg;
22510 #if VPP_API_TEST_BUILTIN == 0
22511   foreach_standalone_reply_msg;
22512 #endif
22513 #undef _
22514
22515 #if (VPP_API_TEST_BUILTIN==0)
22516   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22517
22518   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22519
22520   vam->function_by_name = hash_create_string (0, sizeof (uword));
22521
22522   vam->help_by_name = hash_create_string (0, sizeof (uword));
22523 #endif
22524
22525   /* API messages we can send */
22526 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22527   foreach_vpe_api_msg;
22528 #undef _
22529
22530   /* Help strings */
22531 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22532   foreach_vpe_api_msg;
22533 #undef _
22534
22535   /* CLI functions */
22536 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22537   foreach_cli_function;
22538 #undef _
22539
22540   /* Help strings */
22541 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22542   foreach_cli_function;
22543 #undef _
22544 }
22545
22546 #if VPP_API_TEST_BUILTIN
22547 static clib_error_t *
22548 vat_api_hookup_shim (vlib_main_t * vm)
22549 {
22550   vat_api_hookup (&vat_main);
22551   return 0;
22552 }
22553
22554 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22555 #endif
22556
22557 /*
22558  * fd.io coding-style-patch-verification: ON
22559  *
22560  * Local Variables:
22561  * eval: (c-set-style "gnu")
22562  * End:
22563  */