tap: add support to configure tap interface host MTU size
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61 #include <vlibapi/api_types_inlines.h>
62
63 #include <inttypes.h>
64 #include <sys/stat.h>
65
66 #define vl_typedefs             /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_typedefs
69
70 /* declare message handlers for each api */
71
72 #define vl_endianfun            /* define message structures */
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_endianfun
75
76 /* instantiate all the print functions we know about */
77 #if VPP_API_TEST_BUILTIN == 0
78 #define vl_print(handle, ...)
79 #else
80 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
81 #endif
82 #define vl_printfun
83 #include <vpp/api/vpe_all_api_h.h>
84 #undef vl_printfun
85
86 #define __plugin_msg_base 0
87 #include <vlibapi/vat_helper_macros.h>
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   vam->socket_client_main = &socket_client_main;
103   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
104                                       "vpp_api_test",
105                                       0 /* default socket rx, tx buffer */ )))
106     return rv;
107   /* vpp expects the client index in network order */
108   vam->my_client_index = htonl (socket_client_main.client_index);
109   return 0;
110 }
111 #else /* vpp built-in case, we don't do sockets... */
112 int
113 vat_socket_connect (vat_main_t * vam)
114 {
115   return 0;
116 }
117
118 int
119 vl_socket_client_read (int wait)
120 {
121   return -1;
122 };
123
124 int
125 vl_socket_client_write ()
126 {
127   return -1;
128 };
129
130 void *
131 vl_socket_client_msg_alloc (int nbytes)
132 {
133   return 0;
134 }
135 #endif
136
137
138 f64
139 vat_time_now (vat_main_t * vam)
140 {
141 #if VPP_API_TEST_BUILTIN
142   return vlib_time_now (vam->vlib_main);
143 #else
144   return clib_time_now (&vam->clib_time);
145 #endif
146 }
147
148 void
149 errmsg (char *fmt, ...)
150 {
151   vat_main_t *vam = &vat_main;
152   va_list va;
153   u8 *s;
154
155   va_start (va, fmt);
156   s = va_format (0, fmt, &va);
157   va_end (va);
158
159   vec_add1 (s, 0);
160
161 #if VPP_API_TEST_BUILTIN
162   vlib_cli_output (vam->vlib_main, (char *) s);
163 #else
164   {
165     if (vam->ifp != stdin)
166       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
167                vam->input_line_number);
168     fformat (vam->ofp, (char *) s);
169     fflush (vam->ofp);
170   }
171 #endif
172
173   vec_free (s);
174 }
175
176 #if VPP_API_TEST_BUILTIN == 0
177 static uword
178 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
179 {
180   vat_main_t *vam = va_arg (*args, vat_main_t *);
181   u32 *result = va_arg (*args, u32 *);
182   u8 *if_name;
183   uword *p;
184
185   if (!unformat (input, "%s", &if_name))
186     return 0;
187
188   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
189   if (p == 0)
190     return 0;
191   *result = p[0];
192   return 1;
193 }
194
195 static uword
196 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
197 {
198   return 0;
199 }
200
201 /* Parse an IP4 address %d.%d.%d.%d. */
202 uword
203 unformat_ip4_address (unformat_input_t * input, va_list * args)
204 {
205   u8 *result = va_arg (*args, u8 *);
206   unsigned a[4];
207
208   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
209     return 0;
210
211   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
212     return 0;
213
214   result[0] = a[0];
215   result[1] = a[1];
216   result[2] = a[2];
217   result[3] = a[3];
218
219   return 1;
220 }
221
222 uword
223 unformat_ethernet_address (unformat_input_t * input, va_list * args)
224 {
225   u8 *result = va_arg (*args, u8 *);
226   u32 i, a[6];
227
228   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
229                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
230     return 0;
231
232   /* Check range. */
233   for (i = 0; i < 6; i++)
234     if (a[i] >= (1 << 8))
235       return 0;
236
237   for (i = 0; i < 6; i++)
238     result[i] = a[i];
239
240   return 1;
241 }
242
243 /* Returns ethernet type as an int in host byte order. */
244 uword
245 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
246                                         va_list * args)
247 {
248   u16 *result = va_arg (*args, u16 *);
249   int type;
250
251   /* Numeric type. */
252   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
253     {
254       if (type >= (1 << 16))
255         return 0;
256       *result = type;
257       return 1;
258     }
259   return 0;
260 }
261
262 /* Parse an IP6 address. */
263 uword
264 unformat_ip6_address (unformat_input_t * input, va_list * args)
265 {
266   ip6_address_t *result = va_arg (*args, ip6_address_t *);
267   u16 hex_quads[8];
268   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
269   uword c, n_colon, double_colon_index;
270
271   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
272   double_colon_index = ARRAY_LEN (hex_quads);
273   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
274     {
275       hex_digit = 16;
276       if (c >= '0' && c <= '9')
277         hex_digit = c - '0';
278       else if (c >= 'a' && c <= 'f')
279         hex_digit = c + 10 - 'a';
280       else if (c >= 'A' && c <= 'F')
281         hex_digit = c + 10 - 'A';
282       else if (c == ':' && n_colon < 2)
283         n_colon++;
284       else
285         {
286           unformat_put_input (input);
287           break;
288         }
289
290       /* Too many hex quads. */
291       if (n_hex_quads >= ARRAY_LEN (hex_quads))
292         return 0;
293
294       if (hex_digit < 16)
295         {
296           hex_quad = (hex_quad << 4) | hex_digit;
297
298           /* Hex quad must fit in 16 bits. */
299           if (n_hex_digits >= 4)
300             return 0;
301
302           n_colon = 0;
303           n_hex_digits++;
304         }
305
306       /* Save position of :: */
307       if (n_colon == 2)
308         {
309           /* More than one :: ? */
310           if (double_colon_index < ARRAY_LEN (hex_quads))
311             return 0;
312           double_colon_index = n_hex_quads;
313         }
314
315       if (n_colon > 0 && n_hex_digits > 0)
316         {
317           hex_quads[n_hex_quads++] = hex_quad;
318           hex_quad = 0;
319           n_hex_digits = 0;
320         }
321     }
322
323   if (n_hex_digits > 0)
324     hex_quads[n_hex_quads++] = hex_quad;
325
326   {
327     word i;
328
329     /* Expand :: to appropriate number of zero hex quads. */
330     if (double_colon_index < ARRAY_LEN (hex_quads))
331       {
332         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
333
334         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
335           hex_quads[n_zero + i] = hex_quads[i];
336
337         for (i = 0; i < n_zero; i++)
338           hex_quads[double_colon_index + i] = 0;
339
340         n_hex_quads = ARRAY_LEN (hex_quads);
341       }
342
343     /* Too few hex quads given. */
344     if (n_hex_quads < ARRAY_LEN (hex_quads))
345       return 0;
346
347     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
348       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
349
350     return 1;
351   }
352 }
353
354 uword
355 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
356 {
357   u32 *r = va_arg (*args, u32 *);
358
359   if (0);
360 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
361   foreach_ipsec_policy_action
362 #undef _
363     else
364     return 0;
365   return 1;
366 }
367
368 u8 *
369 format_ipsec_crypto_alg (u8 * s, va_list * args)
370 {
371   u32 i = va_arg (*args, u32);
372   u8 *t = 0;
373
374   switch (i)
375     {
376 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
377       foreach_ipsec_crypto_alg
378 #undef _
379     default:
380       return format (s, "unknown");
381     }
382   return format (s, "%s", t);
383 }
384
385 u8 *
386 format_ipsec_integ_alg (u8 * s, va_list * args)
387 {
388   u32 i = va_arg (*args, u32);
389   u8 *t = 0;
390
391   switch (i)
392     {
393 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
394       foreach_ipsec_integ_alg
395 #undef _
396     default:
397       return format (s, "unknown");
398     }
399   return format (s, "%s", t);
400 }
401
402 #else /* VPP_API_TEST_BUILTIN == 1 */
403 static uword
404 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
405 {
406   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
407   vnet_main_t *vnm = vnet_get_main ();
408   u32 *result = va_arg (*args, u32 *);
409
410   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
411 }
412
413 static uword
414 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
415 {
416   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
417   vnet_main_t *vnm = vnet_get_main ();
418   u32 *result = va_arg (*args, u32 *);
419
420   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
421 }
422
423 #endif /* VPP_API_TEST_BUILTIN */
424
425 uword
426 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
432   foreach_ipsec_crypto_alg
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
446   foreach_ipsec_integ_alg
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 #if (VPP_API_TEST_BUILTIN==0)
571
572 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
573 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
574 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
575 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
576
577 uword
578 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
579 {
580   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
581   mfib_itf_attribute_t attr;
582
583   old = *iflags;
584   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
585   {
586     if (unformat (input, mfib_itf_flag_long_names[attr]))
587       *iflags |= (1 << attr);
588   }
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_names[attr]))
592       *iflags |= (1 << attr);
593   }
594
595   return (old == *iflags ? 0 : 1);
596 }
597
598 uword
599 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
602   mfib_entry_attribute_t attr;
603
604   old = *eflags;
605   FOR_EACH_MFIB_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_flag_long_names[attr]))
608       *eflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_names[attr]))
613       *eflags |= (1 << attr);
614   }
615
616   return (old == *eflags ? 0 : 1);
617 }
618
619 u8 *
620 format_ip4_address (u8 * s, va_list * args)
621 {
622   u8 *a = va_arg (*args, u8 *);
623   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
624 }
625
626 u8 *
627 format_ip6_address (u8 * s, va_list * args)
628 {
629   ip6_address_t *a = va_arg (*args, ip6_address_t *);
630   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
631
632   i_max_n_zero = ARRAY_LEN (a->as_u16);
633   max_n_zeros = 0;
634   i_first_zero = i_max_n_zero;
635   n_zeros = 0;
636   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
637     {
638       u32 is_zero = a->as_u16[i] == 0;
639       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
640         {
641           i_first_zero = i;
642           n_zeros = 0;
643         }
644       n_zeros += is_zero;
645       if ((!is_zero && n_zeros > max_n_zeros)
646           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
647         {
648           i_max_n_zero = i_first_zero;
649           max_n_zeros = n_zeros;
650           i_first_zero = ARRAY_LEN (a->as_u16);
651           n_zeros = 0;
652         }
653     }
654
655   last_double_colon = 0;
656   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
657     {
658       if (i == i_max_n_zero && max_n_zeros > 1)
659         {
660           s = format (s, "::");
661           i += max_n_zeros - 1;
662           last_double_colon = 1;
663         }
664       else
665         {
666           s = format (s, "%s%x",
667                       (last_double_colon || i == 0) ? "" : ":",
668                       clib_net_to_host_u16 (a->as_u16[i]));
669           last_double_colon = 0;
670         }
671     }
672
673   return s;
674 }
675
676 /* Format an IP46 address. */
677 u8 *
678 format_ip46_address (u8 * s, va_list * args)
679 {
680   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
681   ip46_type_t type = va_arg (*args, ip46_type_t);
682   int is_ip4 = 1;
683
684   switch (type)
685     {
686     case IP46_TYPE_ANY:
687       is_ip4 = ip46_address_is_ip4 (ip46);
688       break;
689     case IP46_TYPE_IP4:
690       is_ip4 = 1;
691       break;
692     case IP46_TYPE_IP6:
693       is_ip4 = 0;
694       break;
695     }
696
697   return is_ip4 ?
698     format (s, "%U", format_ip4_address, &ip46->ip4) :
699     format (s, "%U", format_ip6_address, &ip46->ip6);
700 }
701
702 u8 *
703 format_ethernet_address (u8 * s, va_list * args)
704 {
705   u8 *a = va_arg (*args, u8 *);
706
707   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
708                  a[0], a[1], a[2], a[3], a[4], a[5]);
709 }
710 #endif
711
712 static void
713 increment_v4_address (vl_api_ip4_address_t * i)
714 {
715   ip4_address_t *a = (ip4_address_t *) i;
716   u32 v;
717
718   v = ntohl (a->as_u32) + 1;
719   a->as_u32 = ntohl (v);
720 }
721
722 static void
723 increment_v6_address (vl_api_ip6_address_t * i)
724 {
725   ip6_address_t *a = (ip6_address_t *) i;
726   u64 v0, v1;
727
728   v0 = clib_net_to_host_u64 (a->as_u64[0]);
729   v1 = clib_net_to_host_u64 (a->as_u64[1]);
730
731   v1 += 1;
732   if (v1 == 0)
733     v0 += 1;
734   a->as_u64[0] = clib_net_to_host_u64 (v0);
735   a->as_u64[1] = clib_net_to_host_u64 (v1);
736 }
737
738 static void
739 increment_address (vl_api_address_t * a)
740 {
741   if (a->af == ADDRESS_IP4)
742     increment_v4_address (&a->un.ip4);
743   else if (a->af == ADDRESS_IP6)
744     increment_v6_address (&a->un.ip6);
745 }
746
747 static void
748 set_ip4_address (vl_api_address_t * a, u32 v)
749 {
750   if (a->af == ADDRESS_IP4)
751     {
752       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
753       i->as_u32 = v;
754     }
755 }
756
757 static void
758 increment_mac_address (u8 * mac)
759 {
760   u64 tmp = *((u64 *) mac);
761   tmp = clib_net_to_host_u64 (tmp);
762   tmp += 1 << 16;               /* skip unused (least significant) octets */
763   tmp = clib_host_to_net_u64 (tmp);
764
765   clib_memcpy (mac, &tmp, 6);
766 }
767
768 static void
769 vat_json_object_add_address (vat_json_node_t * node,
770                              const char *str, const vl_api_address_t * addr)
771 {
772   if (ADDRESS_IP6 == addr->af)
773     {
774       struct in6_addr ip6;
775
776       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
777       vat_json_object_add_ip6 (node, str, ip6);
778     }
779   else
780     {
781       struct in_addr ip4;
782
783       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
784       vat_json_object_add_ip4 (node, str, ip4);
785     }
786 }
787
788 static void
789 vat_json_object_add_prefix (vat_json_node_t * node,
790                             const vl_api_prefix_t * prefix)
791 {
792   vat_json_object_add_uint (node, "address_length", prefix->address_length);
793   vat_json_object_add_address (node, "prefix", &prefix->address);
794 }
795
796 static void vl_api_create_loopback_reply_t_handler
797   (vl_api_create_loopback_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   i32 retval = ntohl (mp->retval);
801
802   vam->retval = retval;
803   vam->regenerate_interface_table = 1;
804   vam->sw_if_index = ntohl (mp->sw_if_index);
805   vam->result_ready = 1;
806 }
807
808 static void vl_api_create_loopback_reply_t_handler_json
809   (vl_api_create_loopback_reply_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t node;
813
814   vat_json_init_object (&node);
815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
817
818   vat_json_print (vam->ofp, &node);
819   vat_json_free (&node);
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_loopback_instance_reply_t_handler
825   (vl_api_create_loopback_instance_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_loopback_instance_reply_t_handler_json
837   (vl_api_create_loopback_instance_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848   vam->retval = ntohl (mp->retval);
849   vam->result_ready = 1;
850 }
851
852 static void vl_api_af_packet_create_reply_t_handler
853   (vl_api_af_packet_create_reply_t * mp)
854 {
855   vat_main_t *vam = &vat_main;
856   i32 retval = ntohl (mp->retval);
857
858   vam->retval = retval;
859   vam->regenerate_interface_table = 1;
860   vam->sw_if_index = ntohl (mp->sw_if_index);
861   vam->result_ready = 1;
862 }
863
864 static void vl_api_af_packet_create_reply_t_handler_json
865   (vl_api_af_packet_create_reply_t * mp)
866 {
867   vat_main_t *vam = &vat_main;
868   vat_json_node_t node;
869
870   vat_json_init_object (&node);
871   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
872   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
873
874   vat_json_print (vam->ofp, &node);
875   vat_json_free (&node);
876
877   vam->retval = ntohl (mp->retval);
878   vam->result_ready = 1;
879 }
880
881 static void vl_api_create_vlan_subif_reply_t_handler
882   (vl_api_create_vlan_subif_reply_t * mp)
883 {
884   vat_main_t *vam = &vat_main;
885   i32 retval = ntohl (mp->retval);
886
887   vam->retval = retval;
888   vam->regenerate_interface_table = 1;
889   vam->sw_if_index = ntohl (mp->sw_if_index);
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_create_vlan_subif_reply_t_handler_json
894   (vl_api_create_vlan_subif_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
902
903   vat_json_print (vam->ofp, &node);
904   vat_json_free (&node);
905
906   vam->retval = ntohl (mp->retval);
907   vam->result_ready = 1;
908 }
909
910 static void vl_api_create_subif_reply_t_handler
911   (vl_api_create_subif_reply_t * mp)
912 {
913   vat_main_t *vam = &vat_main;
914   i32 retval = ntohl (mp->retval);
915
916   vam->retval = retval;
917   vam->regenerate_interface_table = 1;
918   vam->sw_if_index = ntohl (mp->sw_if_index);
919   vam->result_ready = 1;
920 }
921
922 static void vl_api_create_subif_reply_t_handler_json
923   (vl_api_create_subif_reply_t * mp)
924 {
925   vat_main_t *vam = &vat_main;
926   vat_json_node_t node;
927
928   vat_json_init_object (&node);
929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
930   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
931
932   vat_json_print (vam->ofp, &node);
933   vat_json_free (&node);
934
935   vam->retval = ntohl (mp->retval);
936   vam->result_ready = 1;
937 }
938
939 static void vl_api_interface_name_renumber_reply_t_handler
940   (vl_api_interface_name_renumber_reply_t * mp)
941 {
942   vat_main_t *vam = &vat_main;
943   i32 retval = ntohl (mp->retval);
944
945   vam->retval = retval;
946   vam->regenerate_interface_table = 1;
947   vam->result_ready = 1;
948 }
949
950 static void vl_api_interface_name_renumber_reply_t_handler_json
951   (vl_api_interface_name_renumber_reply_t * mp)
952 {
953   vat_main_t *vam = &vat_main;
954   vat_json_node_t node;
955
956   vat_json_init_object (&node);
957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958
959   vat_json_print (vam->ofp, &node);
960   vat_json_free (&node);
961
962   vam->retval = ntohl (mp->retval);
963   vam->result_ready = 1;
964 }
965
966 /*
967  * Special-case: build the interface table, maintain
968  * the next loopback sw_if_index vbl.
969  */
970 static void vl_api_sw_interface_details_t_handler
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   u8 *s = format (0, "%s%c", mp->interface_name, 0);
975
976   hash_set_mem (vam->sw_if_index_by_interface_name, s,
977                 ntohl (mp->sw_if_index));
978
979   /* In sub interface case, fill the sub interface table entry */
980   if (mp->sw_if_index != mp->sup_sw_if_index)
981     {
982       sw_interface_subif_t *sub = NULL;
983
984       vec_add2 (vam->sw_if_subif_table, sub, 1);
985
986       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
987       strncpy ((char *) sub->interface_name, (char *) s,
988                vec_len (sub->interface_name));
989       sub->sw_if_index = ntohl (mp->sw_if_index);
990       sub->sub_id = ntohl (mp->sub_id);
991
992       sub->sub_dot1ad = mp->sub_dot1ad;
993       sub->sub_number_of_tags = mp->sub_number_of_tags;
994       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
995       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
996       sub->sub_exact_match = mp->sub_exact_match;
997       sub->sub_default = mp->sub_default;
998       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
999       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
1000
1001       /* vlan tag rewrite */
1002       sub->vtr_op = ntohl (mp->vtr_op);
1003       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1004       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1005       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1006     }
1007 }
1008
1009 static void vl_api_sw_interface_details_t_handler_json
1010   (vl_api_sw_interface_details_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t *node = NULL;
1014
1015   if (VAT_JSON_ARRAY != vam->json_tree.type)
1016     {
1017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1018       vat_json_init_array (&vam->json_tree);
1019     }
1020   node = vat_json_array_add (&vam->json_tree);
1021
1022   vat_json_init_object (node);
1023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1024   vat_json_object_add_uint (node, "sup_sw_if_index",
1025                             ntohl (mp->sup_sw_if_index));
1026   vat_json_object_add_uint (node, "l2_address_length",
1027                             ntohl (mp->l2_address_length));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1033   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1034   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1035   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1036   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1037   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1038   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1046   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1047   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1048                             mp->sub_outer_vlan_id_any);
1049   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1050                             mp->sub_inner_vlan_id_any);
1051   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1052   vat_json_object_add_uint (node, "vtr_push_dot1q",
1053                             ntohl (mp->vtr_push_dot1q));
1054   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1055   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1056   if (mp->sub_dot1ah)
1057     {
1058       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1059                                        format (0, "%U",
1060                                                format_ethernet_address,
1061                                                &mp->b_dmac));
1062       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1063                                        format (0, "%U",
1064                                                format_ethernet_address,
1065                                                &mp->b_smac));
1066       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1067       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1068     }
1069 }
1070
1071 #if VPP_API_TEST_BUILTIN == 0
1072 static void vl_api_sw_interface_event_t_handler
1073   (vl_api_sw_interface_event_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   if (vam->interface_event_display)
1077     errmsg ("interface flags: sw_if_index %d %s %s",
1078             ntohl (mp->sw_if_index),
1079             mp->admin_up_down ? "admin-up" : "admin-down",
1080             mp->link_up_down ? "link-up" : "link-down");
1081 }
1082 #endif
1083
1084 __clib_unused static void
1085 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1086 {
1087   /* JSON output not supported */
1088 }
1089
1090 static void
1091 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1092 {
1093   vat_main_t *vam = &vat_main;
1094   i32 retval = ntohl (mp->retval);
1095
1096   vam->retval = retval;
1097   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106   api_main_t *am = &api_main;
1107   void *oldheap;
1108   u8 *reply;
1109
1110   vat_json_init_object (&node);
1111   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1112   vat_json_object_add_uint (&node, "reply_in_shmem",
1113                             ntohl (mp->reply_in_shmem));
1114   /* Toss the shared-memory original... */
1115   pthread_mutex_lock (&am->vlib_rp->mutex);
1116   oldheap = svm_push_data_heap (am->vlib_rp);
1117
1118   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1119   vec_free (reply);
1120
1121   svm_pop_heap (oldheap);
1122   pthread_mutex_unlock (&am->vlib_rp->mutex);
1123
1124   vat_json_print (vam->ofp, &node);
1125   vat_json_free (&node);
1126
1127   vam->retval = ntohl (mp->retval);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   i32 retval = ntohl (mp->retval);
1136   u32 length = vl_api_string_len (&mp->reply);
1137
1138   vec_reset_length (vam->cmd_reply);
1139
1140   vam->retval = retval;
1141   if (retval == 0)
1142     {
1143       vec_validate (vam->cmd_reply, length);
1144       clib_memcpy ((char *) (vam->cmd_reply),
1145                    vl_api_from_api_string (&mp->reply), length);
1146       vam->cmd_reply[length] = 0;
1147     }
1148   vam->result_ready = 1;
1149 }
1150
1151 static void
1152 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   vat_json_node_t node;
1156
1157   vec_reset_length (vam->cmd_reply);
1158
1159   vat_json_init_object (&node);
1160   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1161   vat_json_object_add_string_copy (&node, "reply",
1162                                    vl_api_from_api_string (&mp->reply));
1163
1164   vat_json_print (vam->ofp, &node);
1165   vat_json_free (&node);
1166
1167   vam->retval = ntohl (mp->retval);
1168   vam->result_ready = 1;
1169 }
1170
1171 static void vl_api_classify_add_del_table_reply_t_handler
1172   (vl_api_classify_add_del_table_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   i32 retval = ntohl (mp->retval);
1176   if (vam->async_mode)
1177     {
1178       vam->async_errors += (retval < 0);
1179     }
1180   else
1181     {
1182       vam->retval = retval;
1183       if (retval == 0 &&
1184           ((mp->new_table_index != 0xFFFFFFFF) ||
1185            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1186            (mp->match_n_vectors != 0xFFFFFFFF)))
1187         /*
1188          * Note: this is just barely thread-safe, depends on
1189          * the main thread spinning waiting for an answer...
1190          */
1191         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1192                 ntohl (mp->new_table_index),
1193                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1194       vam->result_ready = 1;
1195     }
1196 }
1197
1198 static void vl_api_classify_add_del_table_reply_t_handler_json
1199   (vl_api_classify_add_del_table_reply_t * mp)
1200 {
1201   vat_main_t *vam = &vat_main;
1202   vat_json_node_t node;
1203
1204   vat_json_init_object (&node);
1205   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1206   vat_json_object_add_uint (&node, "new_table_index",
1207                             ntohl (mp->new_table_index));
1208   vat_json_object_add_uint (&node, "skip_n_vectors",
1209                             ntohl (mp->skip_n_vectors));
1210   vat_json_object_add_uint (&node, "match_n_vectors",
1211                             ntohl (mp->match_n_vectors));
1212
1213   vat_json_print (vam->ofp, &node);
1214   vat_json_free (&node);
1215
1216   vam->retval = ntohl (mp->retval);
1217   vam->result_ready = 1;
1218 }
1219
1220 static void vl_api_get_node_index_reply_t_handler
1221   (vl_api_get_node_index_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   i32 retval = ntohl (mp->retval);
1225   if (vam->async_mode)
1226     {
1227       vam->async_errors += (retval < 0);
1228     }
1229   else
1230     {
1231       vam->retval = retval;
1232       if (retval == 0)
1233         errmsg ("node index %d", ntohl (mp->node_index));
1234       vam->result_ready = 1;
1235     }
1236 }
1237
1238 static void vl_api_get_node_index_reply_t_handler_json
1239   (vl_api_get_node_index_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   vat_json_node_t node;
1243
1244   vat_json_init_object (&node);
1245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1246   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1247
1248   vat_json_print (vam->ofp, &node);
1249   vat_json_free (&node);
1250
1251   vam->retval = ntohl (mp->retval);
1252   vam->result_ready = 1;
1253 }
1254
1255 static void vl_api_get_next_index_reply_t_handler
1256   (vl_api_get_next_index_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   i32 retval = ntohl (mp->retval);
1260   if (vam->async_mode)
1261     {
1262       vam->async_errors += (retval < 0);
1263     }
1264   else
1265     {
1266       vam->retval = retval;
1267       if (retval == 0)
1268         errmsg ("next node index %d", ntohl (mp->next_index));
1269       vam->result_ready = 1;
1270     }
1271 }
1272
1273 static void vl_api_get_next_index_reply_t_handler_json
1274   (vl_api_get_next_index_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1282
1283   vat_json_print (vam->ofp, &node);
1284   vat_json_free (&node);
1285
1286   vam->retval = ntohl (mp->retval);
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_add_node_next_reply_t_handler
1291   (vl_api_add_node_next_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   i32 retval = ntohl (mp->retval);
1295   if (vam->async_mode)
1296     {
1297       vam->async_errors += (retval < 0);
1298     }
1299   else
1300     {
1301       vam->retval = retval;
1302       if (retval == 0)
1303         errmsg ("next index %d", ntohl (mp->next_index));
1304       vam->result_ready = 1;
1305     }
1306 }
1307
1308 static void vl_api_add_node_next_reply_t_handler_json
1309   (vl_api_add_node_next_reply_t * mp)
1310 {
1311   vat_main_t *vam = &vat_main;
1312   vat_json_node_t node;
1313
1314   vat_json_init_object (&node);
1315   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1316   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1317
1318   vat_json_print (vam->ofp, &node);
1319   vat_json_free (&node);
1320
1321   vam->retval = ntohl (mp->retval);
1322   vam->result_ready = 1;
1323 }
1324
1325 static void vl_api_show_version_reply_t_handler
1326   (vl_api_show_version_reply_t * mp)
1327 {
1328   vat_main_t *vam = &vat_main;
1329   i32 retval = ntohl (mp->retval);
1330
1331   if (retval >= 0)
1332     {
1333       u8 *s = 0;
1334       char *p = (char *) &mp->program;
1335
1336       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1337       errmsg ("        program: %v\n", s);
1338       vec_free (s);
1339
1340       p +=
1341         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1342       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1343       errmsg ("        version: %v\n", s);
1344       vec_free (s);
1345
1346       p +=
1347         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1348       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1349       errmsg ("     build date: %v\n", s);
1350       vec_free (s);
1351
1352       p +=
1353         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1354       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1355       vec_free (s);
1356
1357       errmsg ("build directory: %v\n", s);
1358     }
1359   vam->retval = retval;
1360   vam->result_ready = 1;
1361 }
1362
1363 static void vl_api_show_version_reply_t_handler_json
1364   (vl_api_show_version_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   char *p = (char *) &mp->program;
1372   vat_json_object_add_string_copy (&node, "program",
1373                                    vl_api_from_api_string ((vl_api_string_t *)
1374                                                            p));
1375   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1376   vat_json_object_add_string_copy (&node, "version",
1377                                    vl_api_from_api_string ((vl_api_string_t *)
1378                                                            p));
1379   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1380   vat_json_object_add_string_copy (&node, "build_date",
1381                                    vl_api_from_api_string ((vl_api_string_t *)
1382                                                            p));
1383   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1384   vat_json_object_add_string_copy (&node, "build_directory",
1385                                    vl_api_from_api_string ((vl_api_string_t *)
1386                                                            p));
1387
1388   vat_json_print (vam->ofp, &node);
1389   vat_json_free (&node);
1390
1391   vam->retval = ntohl (mp->retval);
1392   vam->result_ready = 1;
1393 }
1394
1395 static void vl_api_show_threads_reply_t_handler
1396   (vl_api_show_threads_reply_t * mp)
1397 {
1398   vat_main_t *vam = &vat_main;
1399   i32 retval = ntohl (mp->retval);
1400   int i, count = 0;
1401
1402   if (retval >= 0)
1403     count = ntohl (mp->count);
1404
1405   for (i = 0; i < count; i++)
1406     print (vam->ofp,
1407            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1408            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1409            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1410            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1411            ntohl (mp->thread_data[i].cpu_socket));
1412
1413   vam->retval = retval;
1414   vam->result_ready = 1;
1415 }
1416
1417 static void vl_api_show_threads_reply_t_handler_json
1418   (vl_api_show_threads_reply_t * mp)
1419 {
1420   vat_main_t *vam = &vat_main;
1421   vat_json_node_t node;
1422   vl_api_thread_data_t *td;
1423   i32 retval = ntohl (mp->retval);
1424   int i, count = 0;
1425
1426   if (retval >= 0)
1427     count = ntohl (mp->count);
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", retval);
1431   vat_json_object_add_uint (&node, "count", count);
1432
1433   for (i = 0; i < count; i++)
1434     {
1435       td = &mp->thread_data[i];
1436       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1437       vat_json_object_add_string_copy (&node, "name", td->name);
1438       vat_json_object_add_string_copy (&node, "type", td->type);
1439       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1440       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1441       vat_json_object_add_int (&node, "core", ntohl (td->id));
1442       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1443     }
1444
1445   vat_json_print (vam->ofp, &node);
1446   vat_json_free (&node);
1447
1448   vam->retval = retval;
1449   vam->result_ready = 1;
1450 }
1451
1452 static int
1453 api_show_threads (vat_main_t * vam)
1454 {
1455   vl_api_show_threads_t *mp;
1456   int ret;
1457
1458   print (vam->ofp,
1459          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1460          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1461
1462   M (SHOW_THREADS, mp);
1463
1464   S (mp);
1465   W (ret);
1466   return ret;
1467 }
1468
1469 static void
1470 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1471 {
1472   u32 sw_if_index = ntohl (mp->sw_if_index);
1473   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1474           mp->mac_ip ? "mac/ip binding" : "address resolution",
1475           ntohl (mp->pid), format_ip4_address, mp->ip,
1476           format_vl_api_mac_address, &mp->mac, sw_if_index);
1477 }
1478
1479 static void
1480 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1481 {
1482   /* JSON output not supported */
1483 }
1484
1485 static void
1486 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1487 {
1488   u32 sw_if_index = ntohl (mp->sw_if_index);
1489   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1490           mp->mac_ip ? "mac/ip binding" : "address resolution",
1491           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1492           format_vl_api_mac_address, mp->mac, sw_if_index);
1493 }
1494
1495 static void
1496 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1497 {
1498   /* JSON output not supported */
1499 }
1500
1501 static void
1502 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1503 {
1504   u32 n_macs = ntohl (mp->n_macs);
1505   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1506           ntohl (mp->pid), mp->client_index, n_macs);
1507   int i;
1508   for (i = 0; i < n_macs; i++)
1509     {
1510       vl_api_mac_entry_t *mac = &mp->mac[i];
1511       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1512               i + 1, ntohl (mac->sw_if_index),
1513               format_ethernet_address, mac->mac_addr, mac->action);
1514       if (i == 1000)
1515         break;
1516     }
1517 }
1518
1519 static void
1520 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1521 {
1522   /* JSON output not supported */
1523 }
1524
1525 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1526 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1527
1528 /*
1529  * Special-case: build the bridge domain table, maintain
1530  * the next bd id vbl.
1531  */
1532 static void vl_api_bridge_domain_details_t_handler
1533   (vl_api_bridge_domain_details_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1537   int i;
1538
1539   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1540          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1541
1542   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1543          ntohl (mp->bd_id), mp->learn, mp->forward,
1544          mp->flood, ntohl (mp->bvi_sw_if_index),
1545          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1546
1547   if (n_sw_ifs)
1548     {
1549       vl_api_bridge_domain_sw_if_t *sw_ifs;
1550       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1551              "Interface Name");
1552
1553       sw_ifs = mp->sw_if_details;
1554       for (i = 0; i < n_sw_ifs; i++)
1555         {
1556           u8 *sw_if_name = 0;
1557           u32 sw_if_index;
1558           hash_pair_t *p;
1559
1560           sw_if_index = ntohl (sw_ifs->sw_if_index);
1561
1562           /* *INDENT-OFF* */
1563           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1564                              ({
1565                                if ((u32) p->value[0] == sw_if_index)
1566                                  {
1567                                    sw_if_name = (u8 *)(p->key);
1568                                    break;
1569                                  }
1570                              }));
1571           /* *INDENT-ON* */
1572           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1573                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1574                  "sw_if_index not found!");
1575
1576           sw_ifs++;
1577         }
1578     }
1579 }
1580
1581 static void vl_api_bridge_domain_details_t_handler_json
1582   (vl_api_bridge_domain_details_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   vat_json_node_t *node, *array = NULL;
1586   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1587
1588   if (VAT_JSON_ARRAY != vam->json_tree.type)
1589     {
1590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1591       vat_json_init_array (&vam->json_tree);
1592     }
1593   node = vat_json_array_add (&vam->json_tree);
1594
1595   vat_json_init_object (node);
1596   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1597   vat_json_object_add_uint (node, "flood", mp->flood);
1598   vat_json_object_add_uint (node, "forward", mp->forward);
1599   vat_json_object_add_uint (node, "learn", mp->learn);
1600   vat_json_object_add_uint (node, "bvi_sw_if_index",
1601                             ntohl (mp->bvi_sw_if_index));
1602   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1603   array = vat_json_object_add (node, "sw_if");
1604   vat_json_init_array (array);
1605
1606
1607
1608   if (n_sw_ifs)
1609     {
1610       vl_api_bridge_domain_sw_if_t *sw_ifs;
1611       int i;
1612
1613       sw_ifs = mp->sw_if_details;
1614       for (i = 0; i < n_sw_ifs; i++)
1615         {
1616           node = vat_json_array_add (array);
1617           vat_json_init_object (node);
1618           vat_json_object_add_uint (node, "sw_if_index",
1619                                     ntohl (sw_ifs->sw_if_index));
1620           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1621           sw_ifs++;
1622         }
1623     }
1624 }
1625
1626 static void vl_api_control_ping_reply_t_handler
1627   (vl_api_control_ping_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->result_ready = 1;
1639     }
1640   if (vam->socket_client_main)
1641     vam->socket_client_main->control_pings_outstanding--;
1642 }
1643
1644 static void vl_api_control_ping_reply_t_handler_json
1645   (vl_api_control_ping_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649
1650   if (VAT_JSON_NONE != vam->json_tree.type)
1651     {
1652       vat_json_print (vam->ofp, &vam->json_tree);
1653       vat_json_free (&vam->json_tree);
1654       vam->json_tree.type = VAT_JSON_NONE;
1655     }
1656   else
1657     {
1658       /* just print [] */
1659       vat_json_init_array (&vam->json_tree);
1660       vat_json_print (vam->ofp, &vam->json_tree);
1661       vam->json_tree.type = VAT_JSON_NONE;
1662     }
1663
1664   vam->retval = retval;
1665   vam->result_ready = 1;
1666 }
1667
1668 static void
1669   vl_api_bridge_domain_set_mac_age_reply_t_handler
1670   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1686   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693
1694   vat_json_print (vam->ofp, &node);
1695   vat_json_free (&node);
1696
1697   vam->retval = ntohl (mp->retval);
1698   vam->result_ready = 1;
1699 }
1700
1701 static void
1702 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1703 {
1704   vat_main_t *vam = &vat_main;
1705   i32 retval = ntohl (mp->retval);
1706   if (vam->async_mode)
1707     {
1708       vam->async_errors += (retval < 0);
1709     }
1710   else
1711     {
1712       vam->retval = retval;
1713       vam->result_ready = 1;
1714     }
1715 }
1716
1717 static void vl_api_l2_flags_reply_t_handler_json
1718   (vl_api_l2_flags_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1726                             ntohl (mp->resulting_feature_bitmap));
1727
1728   vat_json_print (vam->ofp, &node);
1729   vat_json_free (&node);
1730
1731   vam->retval = ntohl (mp->retval);
1732   vam->result_ready = 1;
1733 }
1734
1735 static void vl_api_bridge_flags_reply_t_handler
1736   (vl_api_bridge_flags_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_bridge_flags_reply_t_handler_json
1752   (vl_api_bridge_flags_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1760                             ntohl (mp->resulting_feature_bitmap));
1761
1762   vat_json_print (vam->ofp, &node);
1763   vat_json_free (&node);
1764
1765   vam->retval = ntohl (mp->retval);
1766   vam->result_ready = 1;
1767 }
1768
1769 static void
1770 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   i32 retval = ntohl (mp->retval);
1774   if (vam->async_mode)
1775     {
1776       vam->async_errors += (retval < 0);
1777     }
1778   else
1779     {
1780       vam->retval = retval;
1781       vam->sw_if_index = ntohl (mp->sw_if_index);
1782       vam->result_ready = 1;
1783     }
1784
1785 }
1786
1787 static void vl_api_tap_create_v2_reply_t_handler_json
1788   (vl_api_tap_create_v2_reply_t * mp)
1789 {
1790   vat_main_t *vam = &vat_main;
1791   vat_json_node_t node;
1792
1793   vat_json_init_object (&node);
1794   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1795   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1796
1797   vat_json_print (vam->ofp, &node);
1798   vat_json_free (&node);
1799
1800   vam->retval = ntohl (mp->retval);
1801   vam->result_ready = 1;
1802
1803 }
1804
1805 static void
1806 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   i32 retval = ntohl (mp->retval);
1810   if (vam->async_mode)
1811     {
1812       vam->async_errors += (retval < 0);
1813     }
1814   else
1815     {
1816       vam->retval = retval;
1817       vam->result_ready = 1;
1818     }
1819 }
1820
1821 static void vl_api_tap_delete_v2_reply_t_handler_json
1822   (vl_api_tap_delete_v2_reply_t * mp)
1823 {
1824   vat_main_t *vam = &vat_main;
1825   vat_json_node_t node;
1826
1827   vat_json_init_object (&node);
1828   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1829
1830   vat_json_print (vam->ofp, &node);
1831   vat_json_free (&node);
1832
1833   vam->retval = ntohl (mp->retval);
1834   vam->result_ready = 1;
1835 }
1836
1837 static void
1838 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1839                                           mp)
1840 {
1841   vat_main_t *vam = &vat_main;
1842   i32 retval = ntohl (mp->retval);
1843   if (vam->async_mode)
1844     {
1845       vam->async_errors += (retval < 0);
1846     }
1847   else
1848     {
1849       vam->retval = retval;
1850       vam->sw_if_index = ntohl (mp->sw_if_index);
1851       vam->result_ready = 1;
1852     }
1853 }
1854
1855 static void vl_api_virtio_pci_create_reply_t_handler_json
1856   (vl_api_virtio_pci_create_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   vat_json_node_t node;
1860
1861   vat_json_init_object (&node);
1862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1863   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1864
1865   vat_json_print (vam->ofp, &node);
1866   vat_json_free (&node);
1867
1868   vam->retval = ntohl (mp->retval);
1869   vam->result_ready = 1;
1870
1871 }
1872
1873 static void
1874 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1875                                           mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   i32 retval = ntohl (mp->retval);
1879   if (vam->async_mode)
1880     {
1881       vam->async_errors += (retval < 0);
1882     }
1883   else
1884     {
1885       vam->retval = retval;
1886       vam->result_ready = 1;
1887     }
1888 }
1889
1890 static void vl_api_virtio_pci_delete_reply_t_handler_json
1891   (vl_api_virtio_pci_delete_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   vat_json_node_t node;
1895
1896   vat_json_init_object (&node);
1897   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1898
1899   vat_json_print (vam->ofp, &node);
1900   vat_json_free (&node);
1901
1902   vam->retval = ntohl (mp->retval);
1903   vam->result_ready = 1;
1904 }
1905
1906 static void
1907 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   i32 retval = ntohl (mp->retval);
1911
1912   if (vam->async_mode)
1913     {
1914       vam->async_errors += (retval < 0);
1915     }
1916   else
1917     {
1918       vam->retval = retval;
1919       vam->sw_if_index = ntohl (mp->sw_if_index);
1920       vam->result_ready = 1;
1921     }
1922 }
1923
1924 static void vl_api_bond_create_reply_t_handler_json
1925   (vl_api_bond_create_reply_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   vat_json_node_t node;
1929
1930   vat_json_init_object (&node);
1931   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1932   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1933
1934   vat_json_print (vam->ofp, &node);
1935   vat_json_free (&node);
1936
1937   vam->retval = ntohl (mp->retval);
1938   vam->result_ready = 1;
1939 }
1940
1941 static void
1942 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   i32 retval = ntohl (mp->retval);
1946
1947   if (vam->async_mode)
1948     {
1949       vam->async_errors += (retval < 0);
1950     }
1951   else
1952     {
1953       vam->retval = retval;
1954       vam->result_ready = 1;
1955     }
1956 }
1957
1958 static void vl_api_bond_delete_reply_t_handler_json
1959   (vl_api_bond_delete_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   vat_json_node_t node;
1963
1964   vat_json_init_object (&node);
1965   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1966
1967   vat_json_print (vam->ofp, &node);
1968   vat_json_free (&node);
1969
1970   vam->retval = ntohl (mp->retval);
1971   vam->result_ready = 1;
1972 }
1973
1974 static void
1975 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   i32 retval = ntohl (mp->retval);
1979
1980   if (vam->async_mode)
1981     {
1982       vam->async_errors += (retval < 0);
1983     }
1984   else
1985     {
1986       vam->retval = retval;
1987       vam->result_ready = 1;
1988     }
1989 }
1990
1991 static void vl_api_bond_enslave_reply_t_handler_json
1992   (vl_api_bond_enslave_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   vat_json_node_t node;
1996
1997   vat_json_init_object (&node);
1998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1999
2000   vat_json_print (vam->ofp, &node);
2001   vat_json_free (&node);
2002
2003   vam->retval = ntohl (mp->retval);
2004   vam->result_ready = 1;
2005 }
2006
2007 static void
2008 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2009                                           mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   i32 retval = ntohl (mp->retval);
2013
2014   if (vam->async_mode)
2015     {
2016       vam->async_errors += (retval < 0);
2017     }
2018   else
2019     {
2020       vam->retval = retval;
2021       vam->result_ready = 1;
2022     }
2023 }
2024
2025 static void vl_api_bond_detach_slave_reply_t_handler_json
2026   (vl_api_bond_detach_slave_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vat_json_node_t node;
2030
2031   vat_json_init_object (&node);
2032   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2033
2034   vat_json_print (vam->ofp, &node);
2035   vat_json_free (&node);
2036
2037   vam->retval = ntohl (mp->retval);
2038   vam->result_ready = 1;
2039 }
2040
2041 static void vl_api_sw_interface_bond_details_t_handler
2042   (vl_api_sw_interface_bond_details_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045
2046   print (vam->ofp,
2047          "%-16s %-12d %-12U %-13U %-14u %-14u",
2048          mp->interface_name, ntohl (mp->sw_if_index),
2049          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2050          ntohl (mp->active_slaves), ntohl (mp->slaves));
2051 }
2052
2053 static void vl_api_sw_interface_bond_details_t_handler_json
2054   (vl_api_sw_interface_bond_details_t * mp)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   vat_json_node_t *node = NULL;
2058
2059   if (VAT_JSON_ARRAY != vam->json_tree.type)
2060     {
2061       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2062       vat_json_init_array (&vam->json_tree);
2063     }
2064   node = vat_json_array_add (&vam->json_tree);
2065
2066   vat_json_init_object (node);
2067   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2068   vat_json_object_add_string_copy (node, "interface_name",
2069                                    mp->interface_name);
2070   vat_json_object_add_uint (node, "mode", mp->mode);
2071   vat_json_object_add_uint (node, "load_balance", mp->lb);
2072   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2073   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2074 }
2075
2076 static int
2077 api_sw_interface_bond_dump (vat_main_t * vam)
2078 {
2079   vl_api_sw_interface_bond_dump_t *mp;
2080   vl_api_control_ping_t *mp_ping;
2081   int ret;
2082
2083   print (vam->ofp,
2084          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2085          "interface name", "sw_if_index", "mode", "load balance",
2086          "active slaves", "slaves");
2087
2088   /* Get list of bond interfaces */
2089   M (SW_INTERFACE_BOND_DUMP, mp);
2090   S (mp);
2091
2092   /* Use a control ping for synchronization */
2093   MPING (CONTROL_PING, mp_ping);
2094   S (mp_ping);
2095
2096   W (ret);
2097   return ret;
2098 }
2099
2100 static void vl_api_sw_interface_slave_details_t_handler
2101   (vl_api_sw_interface_slave_details_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104
2105   print (vam->ofp,
2106          "%-25s %-12d %-12d %d", mp->interface_name,
2107          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2108 }
2109
2110 static void vl_api_sw_interface_slave_details_t_handler_json
2111   (vl_api_sw_interface_slave_details_t * mp)
2112 {
2113   vat_main_t *vam = &vat_main;
2114   vat_json_node_t *node = NULL;
2115
2116   if (VAT_JSON_ARRAY != vam->json_tree.type)
2117     {
2118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2119       vat_json_init_array (&vam->json_tree);
2120     }
2121   node = vat_json_array_add (&vam->json_tree);
2122
2123   vat_json_init_object (node);
2124   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2125   vat_json_object_add_string_copy (node, "interface_name",
2126                                    mp->interface_name);
2127   vat_json_object_add_uint (node, "passive", mp->is_passive);
2128   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2129 }
2130
2131 static int
2132 api_sw_interface_slave_dump (vat_main_t * vam)
2133 {
2134   unformat_input_t *i = vam->input;
2135   vl_api_sw_interface_slave_dump_t *mp;
2136   vl_api_control_ping_t *mp_ping;
2137   u32 sw_if_index = ~0;
2138   u8 sw_if_index_set = 0;
2139   int ret;
2140
2141   /* Parse args required to build the message */
2142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2143     {
2144       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2145         sw_if_index_set = 1;
2146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2147         sw_if_index_set = 1;
2148       else
2149         break;
2150     }
2151
2152   if (sw_if_index_set == 0)
2153     {
2154       errmsg ("missing vpp interface name. ");
2155       return -99;
2156     }
2157
2158   print (vam->ofp,
2159          "\n%-25s %-12s %-12s %s",
2160          "slave interface name", "sw_if_index", "passive", "long_timeout");
2161
2162   /* Get list of bond interfaces */
2163   M (SW_INTERFACE_SLAVE_DUMP, mp);
2164   mp->sw_if_index = ntohl (sw_if_index);
2165   S (mp);
2166
2167   /* Use a control ping for synchronization */
2168   MPING (CONTROL_PING, mp_ping);
2169   S (mp_ping);
2170
2171   W (ret);
2172   return ret;
2173 }
2174
2175 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2176   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2177 {
2178   vat_main_t *vam = &vat_main;
2179   i32 retval = ntohl (mp->retval);
2180   if (vam->async_mode)
2181     {
2182       vam->async_errors += (retval < 0);
2183     }
2184   else
2185     {
2186       vam->retval = retval;
2187       vam->sw_if_index = ntohl (mp->sw_if_index);
2188       vam->result_ready = 1;
2189     }
2190   vam->regenerate_interface_table = 1;
2191 }
2192
2193 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2194   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2195 {
2196   vat_main_t *vam = &vat_main;
2197   vat_json_node_t node;
2198
2199   vat_json_init_object (&node);
2200   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2201   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2202                             ntohl (mp->sw_if_index));
2203
2204   vat_json_print (vam->ofp, &node);
2205   vat_json_free (&node);
2206
2207   vam->retval = ntohl (mp->retval);
2208   vam->result_ready = 1;
2209 }
2210
2211 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2212   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2213 {
2214   vat_main_t *vam = &vat_main;
2215   i32 retval = ntohl (mp->retval);
2216   if (vam->async_mode)
2217     {
2218       vam->async_errors += (retval < 0);
2219     }
2220   else
2221     {
2222       vam->retval = retval;
2223       vam->sw_if_index = ntohl (mp->sw_if_index);
2224       vam->result_ready = 1;
2225     }
2226 }
2227
2228 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2229   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2230 {
2231   vat_main_t *vam = &vat_main;
2232   vat_json_node_t node;
2233
2234   vat_json_init_object (&node);
2235   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2236   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2237
2238   vat_json_print (vam->ofp, &node);
2239   vat_json_free (&node);
2240
2241   vam->retval = ntohl (mp->retval);
2242   vam->result_ready = 1;
2243 }
2244
2245 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2246   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   i32 retval = ntohl (mp->retval);
2250   if (vam->async_mode)
2251     {
2252       vam->async_errors += (retval < 0);
2253     }
2254   else
2255     {
2256       vam->retval = retval;
2257       vam->result_ready = 1;
2258     }
2259 }
2260
2261 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2262   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t node;
2266
2267   vat_json_init_object (&node);
2268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269   vat_json_object_add_uint (&node, "fwd_entry_index",
2270                             clib_net_to_host_u32 (mp->fwd_entry_index));
2271
2272   vat_json_print (vam->ofp, &node);
2273   vat_json_free (&node);
2274
2275   vam->retval = ntohl (mp->retval);
2276   vam->result_ready = 1;
2277 }
2278
2279 u8 *
2280 format_lisp_transport_protocol (u8 * s, va_list * args)
2281 {
2282   u32 proto = va_arg (*args, u32);
2283
2284   switch (proto)
2285     {
2286     case 1:
2287       return format (s, "udp");
2288     case 2:
2289       return format (s, "api");
2290     default:
2291       return 0;
2292     }
2293   return 0;
2294 }
2295
2296 static void vl_api_one_get_transport_protocol_reply_t_handler
2297   (vl_api_one_get_transport_protocol_reply_t * mp)
2298 {
2299   vat_main_t *vam = &vat_main;
2300   i32 retval = ntohl (mp->retval);
2301   if (vam->async_mode)
2302     {
2303       vam->async_errors += (retval < 0);
2304     }
2305   else
2306     {
2307       u32 proto = mp->protocol;
2308       print (vam->ofp, "Transport protocol: %U",
2309              format_lisp_transport_protocol, proto);
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312     }
2313 }
2314
2315 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2316   (vl_api_one_get_transport_protocol_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   vat_json_node_t node;
2320   u8 *s;
2321
2322   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2323   vec_add1 (s, 0);
2324
2325   vat_json_init_object (&node);
2326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2327   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2328
2329   vec_free (s);
2330   vat_json_print (vam->ofp, &node);
2331   vat_json_free (&node);
2332
2333   vam->retval = ntohl (mp->retval);
2334   vam->result_ready = 1;
2335 }
2336
2337 static void vl_api_one_add_del_locator_set_reply_t_handler
2338   (vl_api_one_add_del_locator_set_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   i32 retval = ntohl (mp->retval);
2342   if (vam->async_mode)
2343     {
2344       vam->async_errors += (retval < 0);
2345     }
2346   else
2347     {
2348       vam->retval = retval;
2349       vam->result_ready = 1;
2350     }
2351 }
2352
2353 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2354   (vl_api_one_add_del_locator_set_reply_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   vat_json_node_t node;
2358
2359   vat_json_init_object (&node);
2360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2361   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2362
2363   vat_json_print (vam->ofp, &node);
2364   vat_json_free (&node);
2365
2366   vam->retval = ntohl (mp->retval);
2367   vam->result_ready = 1;
2368 }
2369
2370 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2371   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2372 {
2373   vat_main_t *vam = &vat_main;
2374   i32 retval = ntohl (mp->retval);
2375   if (vam->async_mode)
2376     {
2377       vam->async_errors += (retval < 0);
2378     }
2379   else
2380     {
2381       vam->retval = retval;
2382       vam->sw_if_index = ntohl (mp->sw_if_index);
2383       vam->result_ready = 1;
2384     }
2385   vam->regenerate_interface_table = 1;
2386 }
2387
2388 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2389   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2390 {
2391   vat_main_t *vam = &vat_main;
2392   vat_json_node_t node;
2393
2394   vat_json_init_object (&node);
2395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2397
2398   vat_json_print (vam->ofp, &node);
2399   vat_json_free (&node);
2400
2401   vam->retval = ntohl (mp->retval);
2402   vam->result_ready = 1;
2403 }
2404
2405 static void vl_api_vxlan_offload_rx_reply_t_handler
2406   (vl_api_vxlan_offload_rx_reply_t * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   i32 retval = ntohl (mp->retval);
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->result_ready = 1;
2418     }
2419 }
2420
2421 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2422   (vl_api_vxlan_offload_rx_reply_t * mp)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   vat_json_node_t node;
2426
2427   vat_json_init_object (&node);
2428   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2429
2430   vat_json_print (vam->ofp, &node);
2431   vat_json_free (&node);
2432
2433   vam->retval = ntohl (mp->retval);
2434   vam->result_ready = 1;
2435 }
2436
2437 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2438   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2439 {
2440   vat_main_t *vam = &vat_main;
2441   i32 retval = ntohl (mp->retval);
2442   if (vam->async_mode)
2443     {
2444       vam->async_errors += (retval < 0);
2445     }
2446   else
2447     {
2448       vam->retval = retval;
2449       vam->sw_if_index = ntohl (mp->sw_if_index);
2450       vam->result_ready = 1;
2451     }
2452 }
2453
2454 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2455   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   vat_json_node_t node;
2459
2460   vat_json_init_object (&node);
2461   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2462   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2463
2464   vat_json_print (vam->ofp, &node);
2465   vat_json_free (&node);
2466
2467   vam->retval = ntohl (mp->retval);
2468   vam->result_ready = 1;
2469 }
2470
2471 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2472   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2473 {
2474   vat_main_t *vam = &vat_main;
2475   i32 retval = ntohl (mp->retval);
2476   if (vam->async_mode)
2477     {
2478       vam->async_errors += (retval < 0);
2479     }
2480   else
2481     {
2482       vam->retval = retval;
2483       vam->sw_if_index = ntohl (mp->sw_if_index);
2484       vam->result_ready = 1;
2485     }
2486   vam->regenerate_interface_table = 1;
2487 }
2488
2489 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2490   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2491 {
2492   vat_main_t *vam = &vat_main;
2493   vat_json_node_t node;
2494
2495   vat_json_init_object (&node);
2496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2497   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2498
2499   vat_json_print (vam->ofp, &node);
2500   vat_json_free (&node);
2501
2502   vam->retval = ntohl (mp->retval);
2503   vam->result_ready = 1;
2504 }
2505
2506 static void vl_api_gre_tunnel_add_del_reply_t_handler
2507   (vl_api_gre_tunnel_add_del_reply_t * mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   i32 retval = ntohl (mp->retval);
2511   if (vam->async_mode)
2512     {
2513       vam->async_errors += (retval < 0);
2514     }
2515   else
2516     {
2517       vam->retval = retval;
2518       vam->sw_if_index = ntohl (mp->sw_if_index);
2519       vam->result_ready = 1;
2520     }
2521 }
2522
2523 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2524   (vl_api_gre_tunnel_add_del_reply_t * mp)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   vat_json_node_t node;
2528
2529   vat_json_init_object (&node);
2530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2532
2533   vat_json_print (vam->ofp, &node);
2534   vat_json_free (&node);
2535
2536   vam->retval = ntohl (mp->retval);
2537   vam->result_ready = 1;
2538 }
2539
2540 static void vl_api_create_vhost_user_if_reply_t_handler
2541   (vl_api_create_vhost_user_if_reply_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   i32 retval = ntohl (mp->retval);
2545   if (vam->async_mode)
2546     {
2547       vam->async_errors += (retval < 0);
2548     }
2549   else
2550     {
2551       vam->retval = retval;
2552       vam->sw_if_index = ntohl (mp->sw_if_index);
2553       vam->result_ready = 1;
2554     }
2555   vam->regenerate_interface_table = 1;
2556 }
2557
2558 static void vl_api_create_vhost_user_if_reply_t_handler_json
2559   (vl_api_create_vhost_user_if_reply_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vat_json_node_t node;
2563
2564   vat_json_init_object (&node);
2565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2566   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2567
2568   vat_json_print (vam->ofp, &node);
2569   vat_json_free (&node);
2570
2571   vam->retval = ntohl (mp->retval);
2572   vam->result_ready = 1;
2573 }
2574
2575 static void vl_api_dns_resolve_name_reply_t_handler
2576   (vl_api_dns_resolve_name_reply_t * mp)
2577 {
2578   vat_main_t *vam = &vat_main;
2579   i32 retval = ntohl (mp->retval);
2580   if (vam->async_mode)
2581     {
2582       vam->async_errors += (retval < 0);
2583     }
2584   else
2585     {
2586       vam->retval = retval;
2587       vam->result_ready = 1;
2588
2589       if (retval == 0)
2590         {
2591           if (mp->ip4_set)
2592             clib_warning ("ip4 address %U", format_ip4_address,
2593                           (ip4_address_t *) mp->ip4_address);
2594           if (mp->ip6_set)
2595             clib_warning ("ip6 address %U", format_ip6_address,
2596                           (ip6_address_t *) mp->ip6_address);
2597         }
2598       else
2599         clib_warning ("retval %d", retval);
2600     }
2601 }
2602
2603 static void vl_api_dns_resolve_name_reply_t_handler_json
2604   (vl_api_dns_resolve_name_reply_t * mp)
2605 {
2606   clib_warning ("not implemented");
2607 }
2608
2609 static void vl_api_dns_resolve_ip_reply_t_handler
2610   (vl_api_dns_resolve_ip_reply_t * mp)
2611 {
2612   vat_main_t *vam = &vat_main;
2613   i32 retval = ntohl (mp->retval);
2614   if (vam->async_mode)
2615     {
2616       vam->async_errors += (retval < 0);
2617     }
2618   else
2619     {
2620       vam->retval = retval;
2621       vam->result_ready = 1;
2622
2623       if (retval == 0)
2624         {
2625           clib_warning ("canonical name %s", mp->name);
2626         }
2627       else
2628         clib_warning ("retval %d", retval);
2629     }
2630 }
2631
2632 static void vl_api_dns_resolve_ip_reply_t_handler_json
2633   (vl_api_dns_resolve_ip_reply_t * mp)
2634 {
2635   clib_warning ("not implemented");
2636 }
2637
2638
2639 static void vl_api_ip_address_details_t_handler
2640   (vl_api_ip_address_details_t * mp)
2641 {
2642   vat_main_t *vam = &vat_main;
2643   static ip_address_details_t empty_ip_address_details = { {0} };
2644   ip_address_details_t *address = NULL;
2645   ip_details_t *current_ip_details = NULL;
2646   ip_details_t *details = NULL;
2647
2648   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2649
2650   if (!details || vam->current_sw_if_index >= vec_len (details)
2651       || !details[vam->current_sw_if_index].present)
2652     {
2653       errmsg ("ip address details arrived but not stored");
2654       errmsg ("ip_dump should be called first");
2655       return;
2656     }
2657
2658   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2659
2660 #define addresses (current_ip_details->addr)
2661
2662   vec_validate_init_empty (addresses, vec_len (addresses),
2663                            empty_ip_address_details);
2664
2665   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2666
2667   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2668   address->prefix_length = mp->prefix.address_length;
2669 #undef addresses
2670 }
2671
2672 static void vl_api_ip_address_details_t_handler_json
2673   (vl_api_ip_address_details_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   vat_json_node_t *node = NULL;
2677
2678   if (VAT_JSON_ARRAY != vam->json_tree.type)
2679     {
2680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2681       vat_json_init_array (&vam->json_tree);
2682     }
2683   node = vat_json_array_add (&vam->json_tree);
2684
2685   vat_json_init_object (node);
2686   vat_json_object_add_prefix (node, &mp->prefix);
2687 }
2688
2689 static void
2690 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   static ip_details_t empty_ip_details = { 0 };
2694   ip_details_t *ip = NULL;
2695   u32 sw_if_index = ~0;
2696
2697   sw_if_index = ntohl (mp->sw_if_index);
2698
2699   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2700                            sw_if_index, empty_ip_details);
2701
2702   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2703                          sw_if_index);
2704
2705   ip->present = 1;
2706 }
2707
2708 static void
2709 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   vat_json_array_add_uint (&vam->json_tree,
2719                            clib_net_to_host_u32 (mp->sw_if_index));
2720 }
2721
2722 static void
2723 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2724 {
2725   u8 *s, i;
2726
2727   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2728               "host_mac %U router_addr %U",
2729               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2730               mp->lease.hostname,
2731               format_ip4_address, mp->lease.host_address,
2732               format_ethernet_address, mp->lease.host_mac,
2733               format_ip4_address, mp->lease.router_address);
2734
2735   for (i = 0; i < mp->lease.count; i++)
2736     s =
2737       format (s, " domain_server_addr %U", format_ip4_address,
2738               mp->lease.domain_server[i].address);
2739
2740   errmsg ((char *) s);
2741   vec_free (s);
2742 }
2743
2744 static void vl_api_dhcp_compl_event_t_handler_json
2745   (vl_api_dhcp_compl_event_t * mp)
2746 {
2747   /* JSON output not supported */
2748 }
2749
2750 static void vl_api_get_first_msg_id_reply_t_handler
2751   (vl_api_get_first_msg_id_reply_t * mp)
2752 {
2753   vat_main_t *vam = &vat_main;
2754   i32 retval = ntohl (mp->retval);
2755
2756   if (vam->async_mode)
2757     {
2758       vam->async_errors += (retval < 0);
2759     }
2760   else
2761     {
2762       vam->retval = retval;
2763       vam->result_ready = 1;
2764     }
2765   if (retval >= 0)
2766     {
2767       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2768     }
2769 }
2770
2771 static void vl_api_get_first_msg_id_reply_t_handler_json
2772   (vl_api_get_first_msg_id_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   vat_json_node_t node;
2776
2777   vat_json_init_object (&node);
2778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2779   vat_json_object_add_uint (&node, "first_msg_id",
2780                             (uint) ntohs (mp->first_msg_id));
2781
2782   vat_json_print (vam->ofp, &node);
2783   vat_json_free (&node);
2784
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void vl_api_get_node_graph_reply_t_handler
2790   (vl_api_get_node_graph_reply_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793   api_main_t *am = &api_main;
2794   i32 retval = ntohl (mp->retval);
2795   u8 *pvt_copy, *reply;
2796   void *oldheap;
2797   vlib_node_t *node;
2798   int i;
2799
2800   if (vam->async_mode)
2801     {
2802       vam->async_errors += (retval < 0);
2803     }
2804   else
2805     {
2806       vam->retval = retval;
2807       vam->result_ready = 1;
2808     }
2809
2810   /* "Should never happen..." */
2811   if (retval != 0)
2812     return;
2813
2814   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2815   pvt_copy = vec_dup (reply);
2816
2817   /* Toss the shared-memory original... */
2818   pthread_mutex_lock (&am->vlib_rp->mutex);
2819   oldheap = svm_push_data_heap (am->vlib_rp);
2820
2821   vec_free (reply);
2822
2823   svm_pop_heap (oldheap);
2824   pthread_mutex_unlock (&am->vlib_rp->mutex);
2825
2826   if (vam->graph_nodes)
2827     {
2828       hash_free (vam->graph_node_index_by_name);
2829
2830       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2831         {
2832           node = vam->graph_nodes[0][i];
2833           vec_free (node->name);
2834           vec_free (node->next_nodes);
2835           vec_free (node);
2836         }
2837       vec_free (vam->graph_nodes[0]);
2838       vec_free (vam->graph_nodes);
2839     }
2840
2841   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2842   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2843   vec_free (pvt_copy);
2844
2845   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2846     {
2847       node = vam->graph_nodes[0][i];
2848       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2849     }
2850 }
2851
2852 static void vl_api_get_node_graph_reply_t_handler_json
2853   (vl_api_get_node_graph_reply_t * mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   api_main_t *am = &api_main;
2857   void *oldheap;
2858   vat_json_node_t node;
2859   u8 *reply;
2860
2861   /* $$$$ make this real? */
2862   vat_json_init_object (&node);
2863   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2864   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2865
2866   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   vat_json_print (vam->ofp, &node);
2878   vat_json_free (&node);
2879
2880   vam->retval = ntohl (mp->retval);
2881   vam->result_ready = 1;
2882 }
2883
2884 static void
2885 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2886 {
2887   vat_main_t *vam = &vat_main;
2888   u8 *s = 0;
2889
2890   if (mp->local)
2891     {
2892       s = format (s, "%=16d%=16d%=16d",
2893                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2894     }
2895   else
2896     {
2897       s = format (s, "%=16U%=16d%=16d",
2898                   mp->is_ipv6 ? format_ip6_address :
2899                   format_ip4_address,
2900                   mp->ip_address, mp->priority, mp->weight);
2901     }
2902
2903   print (vam->ofp, "%v", s);
2904   vec_free (s);
2905 }
2906
2907 static void
2908 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2909 {
2910   vat_main_t *vam = &vat_main;
2911   vat_json_node_t *node = NULL;
2912   struct in6_addr ip6;
2913   struct in_addr ip4;
2914
2915   if (VAT_JSON_ARRAY != vam->json_tree.type)
2916     {
2917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2918       vat_json_init_array (&vam->json_tree);
2919     }
2920   node = vat_json_array_add (&vam->json_tree);
2921   vat_json_init_object (node);
2922
2923   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2924   vat_json_object_add_uint (node, "priority", mp->priority);
2925   vat_json_object_add_uint (node, "weight", mp->weight);
2926
2927   if (mp->local)
2928     vat_json_object_add_uint (node, "sw_if_index",
2929                               clib_net_to_host_u32 (mp->sw_if_index));
2930   else
2931     {
2932       if (mp->is_ipv6)
2933         {
2934           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2935           vat_json_object_add_ip6 (node, "address", ip6);
2936         }
2937       else
2938         {
2939           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2940           vat_json_object_add_ip4 (node, "address", ip4);
2941         }
2942     }
2943 }
2944
2945 static void
2946 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2947                                           mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u8 *ls_name = 0;
2951
2952   ls_name = format (0, "%s", mp->ls_name);
2953
2954   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2955          ls_name);
2956   vec_free (ls_name);
2957 }
2958
2959 static void
2960   vl_api_one_locator_set_details_t_handler_json
2961   (vl_api_one_locator_set_details_t * mp)
2962 {
2963   vat_main_t *vam = &vat_main;
2964   vat_json_node_t *node = 0;
2965   u8 *ls_name = 0;
2966
2967   ls_name = format (0, "%s", mp->ls_name);
2968   vec_add1 (ls_name, 0);
2969
2970   if (VAT_JSON_ARRAY != vam->json_tree.type)
2971     {
2972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2973       vat_json_init_array (&vam->json_tree);
2974     }
2975   node = vat_json_array_add (&vam->json_tree);
2976
2977   vat_json_init_object (node);
2978   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2979   vat_json_object_add_uint (node, "ls_index",
2980                             clib_net_to_host_u32 (mp->ls_index));
2981   vec_free (ls_name);
2982 }
2983
2984 typedef struct
2985 {
2986   u32 spi;
2987   u8 si;
2988 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2989
2990 uword
2991 unformat_nsh_address (unformat_input_t * input, va_list * args)
2992 {
2993   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2994   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2995 }
2996
2997 u8 *
2998 format_nsh_address_vat (u8 * s, va_list * args)
2999 {
3000   nsh_t *a = va_arg (*args, nsh_t *);
3001   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3002 }
3003
3004 static u8 *
3005 format_lisp_flat_eid (u8 * s, va_list * args)
3006 {
3007   u32 type = va_arg (*args, u32);
3008   u8 *eid = va_arg (*args, u8 *);
3009   u32 eid_len = va_arg (*args, u32);
3010
3011   switch (type)
3012     {
3013     case 0:
3014       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3015     case 1:
3016       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3017     case 2:
3018       return format (s, "%U", format_ethernet_address, eid);
3019     case 3:
3020       return format (s, "%U", format_nsh_address_vat, eid);
3021     }
3022   return 0;
3023 }
3024
3025 static u8 *
3026 format_lisp_eid_vat (u8 * s, va_list * args)
3027 {
3028   u32 type = va_arg (*args, u32);
3029   u8 *eid = va_arg (*args, u8 *);
3030   u32 eid_len = va_arg (*args, u32);
3031   u8 *seid = va_arg (*args, u8 *);
3032   u32 seid_len = va_arg (*args, u32);
3033   u32 is_src_dst = va_arg (*args, u32);
3034
3035   if (is_src_dst)
3036     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3037
3038   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3039
3040   return s;
3041 }
3042
3043 static void
3044 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3045 {
3046   vat_main_t *vam = &vat_main;
3047   u8 *s = 0, *eid = 0;
3048
3049   if (~0 == mp->locator_set_index)
3050     s = format (0, "action: %d", mp->action);
3051   else
3052     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3053
3054   eid = format (0, "%U", format_lisp_eid_vat,
3055                 mp->eid_type,
3056                 mp->eid,
3057                 mp->eid_prefix_len,
3058                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3059   vec_add1 (eid, 0);
3060
3061   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3062          clib_net_to_host_u32 (mp->vni),
3063          eid,
3064          mp->is_local ? "local" : "remote",
3065          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3066          clib_net_to_host_u16 (mp->key_id), mp->key);
3067
3068   vec_free (s);
3069   vec_free (eid);
3070 }
3071
3072 static void
3073 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3074                                              * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   vat_json_node_t *node = 0;
3078   u8 *eid = 0;
3079
3080   if (VAT_JSON_ARRAY != vam->json_tree.type)
3081     {
3082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3083       vat_json_init_array (&vam->json_tree);
3084     }
3085   node = vat_json_array_add (&vam->json_tree);
3086
3087   vat_json_init_object (node);
3088   if (~0 == mp->locator_set_index)
3089     vat_json_object_add_uint (node, "action", mp->action);
3090   else
3091     vat_json_object_add_uint (node, "locator_set_index",
3092                               clib_net_to_host_u32 (mp->locator_set_index));
3093
3094   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3095   if (mp->eid_type == 3)
3096     {
3097       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3098       vat_json_init_object (nsh_json);
3099       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3100       vat_json_object_add_uint (nsh_json, "spi",
3101                                 clib_net_to_host_u32 (nsh->spi));
3102       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3103     }
3104   else
3105     {
3106       eid = format (0, "%U", format_lisp_eid_vat,
3107                     mp->eid_type,
3108                     mp->eid,
3109                     mp->eid_prefix_len,
3110                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3111       vec_add1 (eid, 0);
3112       vat_json_object_add_string_copy (node, "eid", eid);
3113       vec_free (eid);
3114     }
3115   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3116   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3117   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3118
3119   if (mp->key_id)
3120     {
3121       vat_json_object_add_uint (node, "key_id",
3122                                 clib_net_to_host_u16 (mp->key_id));
3123       vat_json_object_add_string_copy (node, "key", mp->key);
3124     }
3125 }
3126
3127 static void
3128 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   u8 *seid = 0, *deid = 0;
3132   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3133
3134   deid = format (0, "%U", format_lisp_eid_vat,
3135                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3136
3137   seid = format (0, "%U", format_lisp_eid_vat,
3138                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3139
3140   vec_add1 (deid, 0);
3141   vec_add1 (seid, 0);
3142
3143   if (mp->is_ip4)
3144     format_ip_address_fcn = format_ip4_address;
3145   else
3146     format_ip_address_fcn = format_ip6_address;
3147
3148
3149   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3150          clib_net_to_host_u32 (mp->vni),
3151          seid, deid,
3152          format_ip_address_fcn, mp->lloc,
3153          format_ip_address_fcn, mp->rloc,
3154          clib_net_to_host_u32 (mp->pkt_count),
3155          clib_net_to_host_u32 (mp->bytes));
3156
3157   vec_free (deid);
3158   vec_free (seid);
3159 }
3160
3161 static void
3162 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3163 {
3164   struct in6_addr ip6;
3165   struct in_addr ip4;
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t *node = 0;
3168   u8 *deid = 0, *seid = 0;
3169
3170   if (VAT_JSON_ARRAY != vam->json_tree.type)
3171     {
3172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3173       vat_json_init_array (&vam->json_tree);
3174     }
3175   node = vat_json_array_add (&vam->json_tree);
3176
3177   vat_json_init_object (node);
3178   deid = format (0, "%U", format_lisp_eid_vat,
3179                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3180
3181   seid = format (0, "%U", format_lisp_eid_vat,
3182                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3183
3184   vec_add1 (deid, 0);
3185   vec_add1 (seid, 0);
3186
3187   vat_json_object_add_string_copy (node, "seid", seid);
3188   vat_json_object_add_string_copy (node, "deid", deid);
3189   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3190
3191   if (mp->is_ip4)
3192     {
3193       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3194       vat_json_object_add_ip4 (node, "lloc", ip4);
3195       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3196       vat_json_object_add_ip4 (node, "rloc", ip4);
3197     }
3198   else
3199     {
3200       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3201       vat_json_object_add_ip6 (node, "lloc", ip6);
3202       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3203       vat_json_object_add_ip6 (node, "rloc", ip6);
3204     }
3205   vat_json_object_add_uint (node, "pkt_count",
3206                             clib_net_to_host_u32 (mp->pkt_count));
3207   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3208
3209   vec_free (deid);
3210   vec_free (seid);
3211 }
3212
3213 static void
3214   vl_api_one_eid_table_map_details_t_handler
3215   (vl_api_one_eid_table_map_details_t * mp)
3216 {
3217   vat_main_t *vam = &vat_main;
3218
3219   u8 *line = format (0, "%=10d%=10d",
3220                      clib_net_to_host_u32 (mp->vni),
3221                      clib_net_to_host_u32 (mp->dp_table));
3222   print (vam->ofp, "%v", line);
3223   vec_free (line);
3224 }
3225
3226 static void
3227   vl_api_one_eid_table_map_details_t_handler_json
3228   (vl_api_one_eid_table_map_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231   vat_json_node_t *node = NULL;
3232
3233   if (VAT_JSON_ARRAY != vam->json_tree.type)
3234     {
3235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3236       vat_json_init_array (&vam->json_tree);
3237     }
3238   node = vat_json_array_add (&vam->json_tree);
3239   vat_json_init_object (node);
3240   vat_json_object_add_uint (node, "dp_table",
3241                             clib_net_to_host_u32 (mp->dp_table));
3242   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3243 }
3244
3245 static void
3246   vl_api_one_eid_table_vni_details_t_handler
3247   (vl_api_one_eid_table_vni_details_t * mp)
3248 {
3249   vat_main_t *vam = &vat_main;
3250
3251   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3252   print (vam->ofp, "%v", line);
3253   vec_free (line);
3254 }
3255
3256 static void
3257   vl_api_one_eid_table_vni_details_t_handler_json
3258   (vl_api_one_eid_table_vni_details_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   vat_json_node_t *node = NULL;
3262
3263   if (VAT_JSON_ARRAY != vam->json_tree.type)
3264     {
3265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3266       vat_json_init_array (&vam->json_tree);
3267     }
3268   node = vat_json_array_add (&vam->json_tree);
3269   vat_json_init_object (node);
3270   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3271 }
3272
3273 static void
3274   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3275   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3281   print (vam->ofp, "fallback threshold value: %d", mp->value);
3282
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3289   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t _node, *node = &_node;
3293   int retval = clib_net_to_host_u32 (mp->retval);
3294
3295   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3296   vat_json_init_object (node);
3297   vat_json_object_add_uint (node, "value", mp->value);
3298
3299   vat_json_print (vam->ofp, node);
3300   vat_json_free (node);
3301
3302   vam->retval = retval;
3303   vam->result_ready = 1;
3304 }
3305
3306 static void
3307   vl_api_show_one_map_register_state_reply_t_handler
3308   (vl_api_show_one_map_register_state_reply_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   int retval = clib_net_to_host_u32 (mp->retval);
3312
3313   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317 }
3318
3319 static void
3320   vl_api_show_one_map_register_state_reply_t_handler_json
3321   (vl_api_show_one_map_register_state_reply_t * mp)
3322 {
3323   vat_main_t *vam = &vat_main;
3324   vat_json_node_t _node, *node = &_node;
3325   int retval = clib_net_to_host_u32 (mp->retval);
3326
3327   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_string_copy (node, "state", s);
3331
3332   vat_json_print (vam->ofp, node);
3333   vat_json_free (node);
3334
3335   vam->retval = retval;
3336   vam->result_ready = 1;
3337   vec_free (s);
3338 }
3339
3340 static void
3341   vl_api_show_one_rloc_probe_state_reply_t_handler
3342   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345   int retval = clib_net_to_host_u32 (mp->retval);
3346
3347   if (retval)
3348     goto end;
3349
3350   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3351 end:
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3358   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   vat_json_node_t _node, *node = &_node;
3362   int retval = clib_net_to_host_u32 (mp->retval);
3363
3364   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3365   vat_json_init_object (node);
3366   vat_json_object_add_string_copy (node, "state", s);
3367
3368   vat_json_print (vam->ofp, node);
3369   vat_json_free (node);
3370
3371   vam->retval = retval;
3372   vam->result_ready = 1;
3373   vec_free (s);
3374 }
3375
3376 static void
3377   vl_api_show_one_stats_enable_disable_reply_t_handler
3378   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   int retval = clib_net_to_host_u32 (mp->retval);
3382
3383   if (retval)
3384     goto end;
3385
3386   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3387 end:
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3394   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397   vat_json_node_t _node, *node = &_node;
3398   int retval = clib_net_to_host_u32 (mp->retval);
3399
3400   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3401   vat_json_init_object (node);
3402   vat_json_object_add_string_copy (node, "state", s);
3403
3404   vat_json_print (vam->ofp, node);
3405   vat_json_free (node);
3406
3407   vam->retval = retval;
3408   vam->result_ready = 1;
3409   vec_free (s);
3410 }
3411
3412 static void
3413 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3414 {
3415   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3416   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3417   e->vni = clib_net_to_host_u32 (e->vni);
3418 }
3419
3420 static void
3421   gpe_fwd_entries_get_reply_t_net_to_host
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   u32 i;
3425
3426   mp->count = clib_net_to_host_u32 (mp->count);
3427   for (i = 0; i < mp->count; i++)
3428     {
3429       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3430     }
3431 }
3432
3433 static u8 *
3434 format_gpe_encap_mode (u8 * s, va_list * args)
3435 {
3436   u32 mode = va_arg (*args, u32);
3437
3438   switch (mode)
3439     {
3440     case 0:
3441       return format (s, "lisp");
3442     case 1:
3443       return format (s, "vxlan");
3444     }
3445   return 0;
3446 }
3447
3448 static void
3449   vl_api_gpe_get_encap_mode_reply_t_handler
3450   (vl_api_gpe_get_encap_mode_reply_t * mp)
3451 {
3452   vat_main_t *vam = &vat_main;
3453
3454   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3455   vam->retval = ntohl (mp->retval);
3456   vam->result_ready = 1;
3457 }
3458
3459 static void
3460   vl_api_gpe_get_encap_mode_reply_t_handler_json
3461   (vl_api_gpe_get_encap_mode_reply_t * mp)
3462 {
3463   vat_main_t *vam = &vat_main;
3464   vat_json_node_t node;
3465
3466   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3467   vec_add1 (encap_mode, 0);
3468
3469   vat_json_init_object (&node);
3470   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3471
3472   vec_free (encap_mode);
3473   vat_json_print (vam->ofp, &node);
3474   vat_json_free (&node);
3475
3476   vam->retval = ntohl (mp->retval);
3477   vam->result_ready = 1;
3478 }
3479
3480 static void
3481   vl_api_gpe_fwd_entry_path_details_t_handler
3482   (vl_api_gpe_fwd_entry_path_details_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3486
3487   if (mp->lcl_loc.is_ip4)
3488     format_ip_address_fcn = format_ip4_address;
3489   else
3490     format_ip_address_fcn = format_ip6_address;
3491
3492   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3493          format_ip_address_fcn, &mp->lcl_loc,
3494          format_ip_address_fcn, &mp->rmt_loc);
3495 }
3496
3497 static void
3498 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3499 {
3500   struct in6_addr ip6;
3501   struct in_addr ip4;
3502
3503   if (loc->is_ip4)
3504     {
3505       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3506       vat_json_object_add_ip4 (n, "address", ip4);
3507     }
3508   else
3509     {
3510       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3511       vat_json_object_add_ip6 (n, "address", ip6);
3512     }
3513   vat_json_object_add_uint (n, "weight", loc->weight);
3514 }
3515
3516 static void
3517   vl_api_gpe_fwd_entry_path_details_t_handler_json
3518   (vl_api_gpe_fwd_entry_path_details_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   vat_json_node_t *node = NULL;
3522   vat_json_node_t *loc_node;
3523
3524   if (VAT_JSON_ARRAY != vam->json_tree.type)
3525     {
3526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3527       vat_json_init_array (&vam->json_tree);
3528     }
3529   node = vat_json_array_add (&vam->json_tree);
3530   vat_json_init_object (node);
3531
3532   loc_node = vat_json_object_add (node, "local_locator");
3533   vat_json_init_object (loc_node);
3534   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3535
3536   loc_node = vat_json_object_add (node, "remote_locator");
3537   vat_json_init_object (loc_node);
3538   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3539 }
3540
3541 static void
3542   vl_api_gpe_fwd_entries_get_reply_t_handler
3543   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3544 {
3545   vat_main_t *vam = &vat_main;
3546   u32 i;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_gpe_fwd_entry_t *e;
3549
3550   if (retval)
3551     goto end;
3552
3553   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3554
3555   for (i = 0; i < mp->count; i++)
3556     {
3557       e = &mp->entries[i];
3558       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3559              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3560              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3561     }
3562
3563 end:
3564   vam->retval = retval;
3565   vam->result_ready = 1;
3566 }
3567
3568 static void
3569   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3570   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3571 {
3572   u8 *s = 0;
3573   vat_main_t *vam = &vat_main;
3574   vat_json_node_t *e = 0, root;
3575   u32 i;
3576   int retval = clib_net_to_host_u32 (mp->retval);
3577   vl_api_gpe_fwd_entry_t *fwd;
3578
3579   if (retval)
3580     goto end;
3581
3582   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3583   vat_json_init_array (&root);
3584
3585   for (i = 0; i < mp->count; i++)
3586     {
3587       e = vat_json_array_add (&root);
3588       fwd = &mp->entries[i];
3589
3590       vat_json_init_object (e);
3591       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3592       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3593       vat_json_object_add_int (e, "vni", fwd->vni);
3594       vat_json_object_add_int (e, "action", fwd->action);
3595
3596       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3597                   fwd->leid_prefix_len);
3598       vec_add1 (s, 0);
3599       vat_json_object_add_string_copy (e, "leid", s);
3600       vec_free (s);
3601
3602       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3603                   fwd->reid_prefix_len);
3604       vec_add1 (s, 0);
3605       vat_json_object_add_string_copy (e, "reid", s);
3606       vec_free (s);
3607     }
3608
3609   vat_json_print (vam->ofp, &root);
3610   vat_json_free (&root);
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3619   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   u32 i, n;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624   vl_api_gpe_native_fwd_rpath_t *r;
3625
3626   if (retval)
3627     goto end;
3628
3629   n = clib_net_to_host_u32 (mp->count);
3630
3631   for (i = 0; i < n; i++)
3632     {
3633       r = &mp->entries[i];
3634       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3635              clib_net_to_host_u32 (r->fib_index),
3636              clib_net_to_host_u32 (r->nh_sw_if_index),
3637              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3638     }
3639
3640 end:
3641   vam->retval = retval;
3642   vam->result_ready = 1;
3643 }
3644
3645 static void
3646   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3647   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3648 {
3649   vat_main_t *vam = &vat_main;
3650   vat_json_node_t root, *e;
3651   u32 i, n;
3652   int retval = clib_net_to_host_u32 (mp->retval);
3653   vl_api_gpe_native_fwd_rpath_t *r;
3654   u8 *s;
3655
3656   if (retval)
3657     goto end;
3658
3659   n = clib_net_to_host_u32 (mp->count);
3660   vat_json_init_array (&root);
3661
3662   for (i = 0; i < n; i++)
3663     {
3664       e = vat_json_array_add (&root);
3665       vat_json_init_object (e);
3666       r = &mp->entries[i];
3667       s =
3668         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3669                 r->nh_addr);
3670       vec_add1 (s, 0);
3671       vat_json_object_add_string_copy (e, "ip4", s);
3672       vec_free (s);
3673
3674       vat_json_object_add_uint (e, "fib_index",
3675                                 clib_net_to_host_u32 (r->fib_index));
3676       vat_json_object_add_uint (e, "nh_sw_if_index",
3677                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3678     }
3679
3680   vat_json_print (vam->ofp, &root);
3681   vat_json_free (&root);
3682
3683 end:
3684   vam->retval = retval;
3685   vam->result_ready = 1;
3686 }
3687
3688 static void
3689   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3690   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3691 {
3692   vat_main_t *vam = &vat_main;
3693   u32 i, n;
3694   int retval = clib_net_to_host_u32 (mp->retval);
3695
3696   if (retval)
3697     goto end;
3698
3699   n = clib_net_to_host_u32 (mp->count);
3700
3701   for (i = 0; i < n; i++)
3702     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3711   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   vat_json_node_t root;
3715   u32 i, n;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722   vat_json_init_array (&root);
3723
3724   for (i = 0; i < n; i++)
3725     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3726
3727   vat_json_print (vam->ofp, &root);
3728   vat_json_free (&root);
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_one_ndp_entries_get_reply_t_handler
3737   (vl_api_one_ndp_entries_get_reply_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   u32 i, n;
3741   int retval = clib_net_to_host_u32 (mp->retval);
3742
3743   if (retval)
3744     goto end;
3745
3746   n = clib_net_to_host_u32 (mp->count);
3747
3748   for (i = 0; i < n; i++)
3749     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3750            format_ethernet_address, mp->entries[i].mac);
3751
3752 end:
3753   vam->retval = retval;
3754   vam->result_ready = 1;
3755 }
3756
3757 static void
3758   vl_api_one_ndp_entries_get_reply_t_handler_json
3759   (vl_api_one_ndp_entries_get_reply_t * mp)
3760 {
3761   u8 *s = 0;
3762   vat_main_t *vam = &vat_main;
3763   vat_json_node_t *e = 0, root;
3764   u32 i, n;
3765   int retval = clib_net_to_host_u32 (mp->retval);
3766   vl_api_one_ndp_entry_t *arp_entry;
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     {
3776       e = vat_json_array_add (&root);
3777       arp_entry = &mp->entries[i];
3778
3779       vat_json_init_object (e);
3780       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3781       vec_add1 (s, 0);
3782
3783       vat_json_object_add_string_copy (e, "mac", s);
3784       vec_free (s);
3785
3786       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3787       vec_add1 (s, 0);
3788       vat_json_object_add_string_copy (e, "ip6", s);
3789       vec_free (s);
3790     }
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_l2_arp_entries_get_reply_t_handler
3802   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3815            format_ethernet_address, mp->entries[i].mac);
3816
3817 end:
3818   vam->retval = retval;
3819   vam->result_ready = 1;
3820 }
3821
3822 static void
3823   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3824   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3825 {
3826   u8 *s = 0;
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t *e = 0, root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831   vl_api_one_l2_arp_entry_t *arp_entry;
3832
3833   if (retval)
3834     goto end;
3835
3836   n = clib_net_to_host_u32 (mp->count);
3837   vat_json_init_array (&root);
3838
3839   for (i = 0; i < n; i++)
3840     {
3841       e = vat_json_array_add (&root);
3842       arp_entry = &mp->entries[i];
3843
3844       vat_json_init_object (e);
3845       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3846       vec_add1 (s, 0);
3847
3848       vat_json_object_add_string_copy (e, "mac", s);
3849       vec_free (s);
3850
3851       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3852       vec_add1 (s, 0);
3853       vat_json_object_add_string_copy (e, "ip4", s);
3854       vec_free (s);
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   u32 i, n;
3870   int retval = clib_net_to_host_u32 (mp->retval);
3871
3872   if (retval)
3873     goto end;
3874
3875   n = clib_net_to_host_u32 (mp->count);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3880     }
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_ndp_bd_get_reply_t_handler_json
3889   (vl_api_one_ndp_bd_get_reply_t * mp)
3890 {
3891   vat_main_t *vam = &vat_main;
3892   vat_json_node_t root;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895
3896   if (retval)
3897     goto end;
3898
3899   n = clib_net_to_host_u32 (mp->count);
3900   vat_json_init_array (&root);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       vat_json_array_add_uint (&root,
3905                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3906     }
3907
3908   vat_json_print (vam->ofp, &root);
3909   vat_json_free (&root);
3910
3911 end:
3912   vam->retval = retval;
3913   vam->result_ready = 1;
3914 }
3915
3916 static void
3917   vl_api_one_l2_arp_bd_get_reply_t_handler
3918   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3919 {
3920   vat_main_t *vam = &vat_main;
3921   u32 i, n;
3922   int retval = clib_net_to_host_u32 (mp->retval);
3923
3924   if (retval)
3925     goto end;
3926
3927   n = clib_net_to_host_u32 (mp->count);
3928
3929   for (i = 0; i < n; i++)
3930     {
3931       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3932     }
3933
3934 end:
3935   vam->retval = retval;
3936   vam->result_ready = 1;
3937 }
3938
3939 static void
3940   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3941   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3942 {
3943   vat_main_t *vam = &vat_main;
3944   vat_json_node_t root;
3945   u32 i, n;
3946   int retval = clib_net_to_host_u32 (mp->retval);
3947
3948   if (retval)
3949     goto end;
3950
3951   n = clib_net_to_host_u32 (mp->count);
3952   vat_json_init_array (&root);
3953
3954   for (i = 0; i < n; i++)
3955     {
3956       vat_json_array_add_uint (&root,
3957                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3958     }
3959
3960   vat_json_print (vam->ofp, &root);
3961   vat_json_free (&root);
3962
3963 end:
3964   vam->retval = retval;
3965   vam->result_ready = 1;
3966 }
3967
3968 static void
3969   vl_api_one_adjacencies_get_reply_t_handler
3970   (vl_api_one_adjacencies_get_reply_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   u32 i, n;
3974   int retval = clib_net_to_host_u32 (mp->retval);
3975   vl_api_one_adjacency_t *a;
3976
3977   if (retval)
3978     goto end;
3979
3980   n = clib_net_to_host_u32 (mp->count);
3981
3982   for (i = 0; i < n; i++)
3983     {
3984       a = &mp->adjacencies[i];
3985       print (vam->ofp, "%U %40U",
3986              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3987              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3988     }
3989
3990 end:
3991   vam->retval = retval;
3992   vam->result_ready = 1;
3993 }
3994
3995 static void
3996   vl_api_one_adjacencies_get_reply_t_handler_json
3997   (vl_api_one_adjacencies_get_reply_t * mp)
3998 {
3999   u8 *s = 0;
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *e = 0, root;
4002   u32 i, n;
4003   int retval = clib_net_to_host_u32 (mp->retval);
4004   vl_api_one_adjacency_t *a;
4005
4006   if (retval)
4007     goto end;
4008
4009   n = clib_net_to_host_u32 (mp->count);
4010   vat_json_init_array (&root);
4011
4012   for (i = 0; i < n; i++)
4013     {
4014       e = vat_json_array_add (&root);
4015       a = &mp->adjacencies[i];
4016
4017       vat_json_init_object (e);
4018       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4019                   a->leid_prefix_len);
4020       vec_add1 (s, 0);
4021       vat_json_object_add_string_copy (e, "leid", s);
4022       vec_free (s);
4023
4024       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4025                   a->reid_prefix_len);
4026       vec_add1 (s, 0);
4027       vat_json_object_add_string_copy (e, "reid", s);
4028       vec_free (s);
4029     }
4030
4031   vat_json_print (vam->ofp, &root);
4032   vat_json_free (&root);
4033
4034 end:
4035   vam->retval = retval;
4036   vam->result_ready = 1;
4037 }
4038
4039 static void
4040 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4041 {
4042   vat_main_t *vam = &vat_main;
4043
4044   print (vam->ofp, "%=20U",
4045          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4046          mp->ip_address);
4047 }
4048
4049 static void
4050   vl_api_one_map_server_details_t_handler_json
4051   (vl_api_one_map_server_details_t * mp)
4052 {
4053   vat_main_t *vam = &vat_main;
4054   vat_json_node_t *node = NULL;
4055   struct in6_addr ip6;
4056   struct in_addr ip4;
4057
4058   if (VAT_JSON_ARRAY != vam->json_tree.type)
4059     {
4060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4061       vat_json_init_array (&vam->json_tree);
4062     }
4063   node = vat_json_array_add (&vam->json_tree);
4064
4065   vat_json_init_object (node);
4066   if (mp->is_ipv6)
4067     {
4068       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4069       vat_json_object_add_ip6 (node, "map-server", ip6);
4070     }
4071   else
4072     {
4073       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4074       vat_json_object_add_ip4 (node, "map-server", ip4);
4075     }
4076 }
4077
4078 static void
4079 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4080                                            * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083
4084   print (vam->ofp, "%=20U",
4085          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4086          mp->ip_address);
4087 }
4088
4089 static void
4090   vl_api_one_map_resolver_details_t_handler_json
4091   (vl_api_one_map_resolver_details_t * mp)
4092 {
4093   vat_main_t *vam = &vat_main;
4094   vat_json_node_t *node = NULL;
4095   struct in6_addr ip6;
4096   struct in_addr ip4;
4097
4098   if (VAT_JSON_ARRAY != vam->json_tree.type)
4099     {
4100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4101       vat_json_init_array (&vam->json_tree);
4102     }
4103   node = vat_json_array_add (&vam->json_tree);
4104
4105   vat_json_init_object (node);
4106   if (mp->is_ipv6)
4107     {
4108       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4109       vat_json_object_add_ip6 (node, "map resolver", ip6);
4110     }
4111   else
4112     {
4113       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4114       vat_json_object_add_ip4 (node, "map resolver", ip4);
4115     }
4116 }
4117
4118 static void
4119 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   i32 retval = ntohl (mp->retval);
4123
4124   if (0 <= retval)
4125     {
4126       print (vam->ofp, "feature: %s\ngpe: %s",
4127              mp->feature_status ? "enabled" : "disabled",
4128              mp->gpe_status ? "enabled" : "disabled");
4129     }
4130
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_show_one_status_reply_t_handler_json
4137   (vl_api_show_one_status_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   vat_json_node_t node;
4141   u8 *gpe_status = NULL;
4142   u8 *feature_status = NULL;
4143
4144   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4145   feature_status = format (0, "%s",
4146                            mp->feature_status ? "enabled" : "disabled");
4147   vec_add1 (gpe_status, 0);
4148   vec_add1 (feature_status, 0);
4149
4150   vat_json_init_object (&node);
4151   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4152   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4153
4154   vec_free (gpe_status);
4155   vec_free (feature_status);
4156
4157   vat_json_print (vam->ofp, &node);
4158   vat_json_free (&node);
4159
4160   vam->retval = ntohl (mp->retval);
4161   vam->result_ready = 1;
4162 }
4163
4164 static void
4165   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4166   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4167 {
4168   vat_main_t *vam = &vat_main;
4169   i32 retval = ntohl (mp->retval);
4170
4171   if (retval >= 0)
4172     {
4173       print (vam->ofp, "%=20s", mp->locator_set_name);
4174     }
4175
4176   vam->retval = retval;
4177   vam->result_ready = 1;
4178 }
4179
4180 static void
4181   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4182   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   vat_json_node_t *node = NULL;
4186
4187   if (VAT_JSON_ARRAY != vam->json_tree.type)
4188     {
4189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4190       vat_json_init_array (&vam->json_tree);
4191     }
4192   node = vat_json_array_add (&vam->json_tree);
4193
4194   vat_json_init_object (node);
4195   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4196
4197   vat_json_print (vam->ofp, node);
4198   vat_json_free (node);
4199
4200   vam->retval = ntohl (mp->retval);
4201   vam->result_ready = 1;
4202 }
4203
4204 static u8 *
4205 format_lisp_map_request_mode (u8 * s, va_list * args)
4206 {
4207   u32 mode = va_arg (*args, u32);
4208
4209   switch (mode)
4210     {
4211     case 0:
4212       return format (0, "dst-only");
4213     case 1:
4214       return format (0, "src-dst");
4215     }
4216   return 0;
4217 }
4218
4219 static void
4220   vl_api_show_one_map_request_mode_reply_t_handler
4221   (vl_api_show_one_map_request_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   i32 retval = ntohl (mp->retval);
4225
4226   if (0 <= retval)
4227     {
4228       u32 mode = mp->mode;
4229       print (vam->ofp, "map_request_mode: %U",
4230              format_lisp_map_request_mode, mode);
4231     }
4232
4233   vam->retval = retval;
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_show_one_map_request_mode_reply_t_handler_json
4239   (vl_api_show_one_map_request_mode_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   vat_json_node_t node;
4243   u8 *s = 0;
4244   u32 mode;
4245
4246   mode = mp->mode;
4247   s = format (0, "%U", format_lisp_map_request_mode, mode);
4248   vec_add1 (s, 0);
4249
4250   vat_json_init_object (&node);
4251   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4252   vat_json_print (vam->ofp, &node);
4253   vat_json_free (&node);
4254
4255   vec_free (s);
4256   vam->retval = ntohl (mp->retval);
4257   vam->result_ready = 1;
4258 }
4259
4260 static void
4261   vl_api_one_show_xtr_mode_reply_t_handler
4262   (vl_api_one_show_xtr_mode_reply_t * mp)
4263 {
4264   vat_main_t *vam = &vat_main;
4265   i32 retval = ntohl (mp->retval);
4266
4267   if (0 <= retval)
4268     {
4269       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4270     }
4271
4272   vam->retval = retval;
4273   vam->result_ready = 1;
4274 }
4275
4276 static void
4277   vl_api_one_show_xtr_mode_reply_t_handler_json
4278   (vl_api_one_show_xtr_mode_reply_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281   vat_json_node_t node;
4282   u8 *status = 0;
4283
4284   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4285   vec_add1 (status, 0);
4286
4287   vat_json_init_object (&node);
4288   vat_json_object_add_string_copy (&node, "status", status);
4289
4290   vec_free (status);
4291
4292   vat_json_print (vam->ofp, &node);
4293   vat_json_free (&node);
4294
4295   vam->retval = ntohl (mp->retval);
4296   vam->result_ready = 1;
4297 }
4298
4299 static void
4300   vl_api_one_show_pitr_mode_reply_t_handler
4301   (vl_api_one_show_pitr_mode_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   i32 retval = ntohl (mp->retval);
4305
4306   if (0 <= retval)
4307     {
4308       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4309     }
4310
4311   vam->retval = retval;
4312   vam->result_ready = 1;
4313 }
4314
4315 static void
4316   vl_api_one_show_pitr_mode_reply_t_handler_json
4317   (vl_api_one_show_pitr_mode_reply_t * mp)
4318 {
4319   vat_main_t *vam = &vat_main;
4320   vat_json_node_t node;
4321   u8 *status = 0;
4322
4323   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4324   vec_add1 (status, 0);
4325
4326   vat_json_init_object (&node);
4327   vat_json_object_add_string_copy (&node, "status", status);
4328
4329   vec_free (status);
4330
4331   vat_json_print (vam->ofp, &node);
4332   vat_json_free (&node);
4333
4334   vam->retval = ntohl (mp->retval);
4335   vam->result_ready = 1;
4336 }
4337
4338 static void
4339   vl_api_one_show_petr_mode_reply_t_handler
4340   (vl_api_one_show_petr_mode_reply_t * mp)
4341 {
4342   vat_main_t *vam = &vat_main;
4343   i32 retval = ntohl (mp->retval);
4344
4345   if (0 <= retval)
4346     {
4347       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4348     }
4349
4350   vam->retval = retval;
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355   vl_api_one_show_petr_mode_reply_t_handler_json
4356   (vl_api_one_show_petr_mode_reply_t * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359   vat_json_node_t node;
4360   u8 *status = 0;
4361
4362   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4363   vec_add1 (status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "status", status);
4367
4368   vec_free (status);
4369
4370   vat_json_print (vam->ofp, &node);
4371   vat_json_free (&node);
4372
4373   vam->retval = ntohl (mp->retval);
4374   vam->result_ready = 1;
4375 }
4376
4377 static void
4378   vl_api_show_one_use_petr_reply_t_handler
4379   (vl_api_show_one_use_petr_reply_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   i32 retval = ntohl (mp->retval);
4383
4384   if (0 <= retval)
4385     {
4386       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4387       if (mp->status)
4388         {
4389           print (vam->ofp, "Proxy-ETR address; %U",
4390                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4391                  mp->address);
4392         }
4393     }
4394
4395   vam->retval = retval;
4396   vam->result_ready = 1;
4397 }
4398
4399 static void
4400   vl_api_show_one_use_petr_reply_t_handler_json
4401   (vl_api_show_one_use_petr_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406   struct in_addr ip4;
4407   struct in6_addr ip6;
4408
4409   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4410   vec_add1 (status, 0);
4411
4412   vat_json_init_object (&node);
4413   vat_json_object_add_string_copy (&node, "status", status);
4414   if (mp->status)
4415     {
4416       if (mp->is_ip4)
4417         {
4418           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4419           vat_json_object_add_ip6 (&node, "address", ip6);
4420         }
4421       else
4422         {
4423           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4424           vat_json_object_add_ip4 (&node, "address", ip4);
4425         }
4426     }
4427
4428   vec_free (status);
4429
4430   vat_json_print (vam->ofp, &node);
4431   vat_json_free (&node);
4432
4433   vam->retval = ntohl (mp->retval);
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_nsh_mapping_reply_t_handler
4439   (vl_api_show_one_nsh_mapping_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   i32 retval = ntohl (mp->retval);
4443
4444   if (0 <= retval)
4445     {
4446       print (vam->ofp, "%-20s%-16s",
4447              mp->is_set ? "set" : "not-set",
4448              mp->is_set ? (char *) mp->locator_set_name : "");
4449     }
4450
4451   vam->retval = retval;
4452   vam->result_ready = 1;
4453 }
4454
4455 static void
4456   vl_api_show_one_nsh_mapping_reply_t_handler_json
4457   (vl_api_show_one_nsh_mapping_reply_t * mp)
4458 {
4459   vat_main_t *vam = &vat_main;
4460   vat_json_node_t node;
4461   u8 *status = 0;
4462
4463   status = format (0, "%s", mp->is_set ? "yes" : "no");
4464   vec_add1 (status, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "is_set", status);
4468   if (mp->is_set)
4469     {
4470       vat_json_object_add_string_copy (&node, "locator_set",
4471                                        mp->locator_set_name);
4472     }
4473
4474   vec_free (status);
4475
4476   vat_json_print (vam->ofp, &node);
4477   vat_json_free (&node);
4478
4479   vam->retval = ntohl (mp->retval);
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_show_one_map_register_ttl_reply_t_handler
4485   (vl_api_show_one_map_register_ttl_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   i32 retval = ntohl (mp->retval);
4489
4490   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4491
4492   if (0 <= retval)
4493     {
4494       print (vam->ofp, "ttl: %u", mp->ttl);
4495     }
4496
4497   vam->retval = retval;
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502   vl_api_show_one_map_register_ttl_reply_t_handler_json
4503   (vl_api_show_one_map_register_ttl_reply_t * mp)
4504 {
4505   vat_main_t *vam = &vat_main;
4506   vat_json_node_t node;
4507
4508   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4509   vat_json_init_object (&node);
4510   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4511
4512   vat_json_print (vam->ofp, &node);
4513   vat_json_free (&node);
4514
4515   vam->retval = ntohl (mp->retval);
4516   vam->result_ready = 1;
4517 }
4518
4519 static void
4520 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4521 {
4522   vat_main_t *vam = &vat_main;
4523   i32 retval = ntohl (mp->retval);
4524
4525   if (0 <= retval)
4526     {
4527       print (vam->ofp, "%-20s%-16s",
4528              mp->status ? "enabled" : "disabled",
4529              mp->status ? (char *) mp->locator_set_name : "");
4530     }
4531
4532   vam->retval = retval;
4533   vam->result_ready = 1;
4534 }
4535
4536 static void
4537 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4538 {
4539   vat_main_t *vam = &vat_main;
4540   vat_json_node_t node;
4541   u8 *status = 0;
4542
4543   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4544   vec_add1 (status, 0);
4545
4546   vat_json_init_object (&node);
4547   vat_json_object_add_string_copy (&node, "status", status);
4548   if (mp->status)
4549     {
4550       vat_json_object_add_string_copy (&node, "locator_set",
4551                                        mp->locator_set_name);
4552     }
4553
4554   vec_free (status);
4555
4556   vat_json_print (vam->ofp, &node);
4557   vat_json_free (&node);
4558
4559   vam->retval = ntohl (mp->retval);
4560   vam->result_ready = 1;
4561 }
4562
4563 static u8 *
4564 format_policer_type (u8 * s, va_list * va)
4565 {
4566   u32 i = va_arg (*va, u32);
4567
4568   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4569     s = format (s, "1r2c");
4570   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4571     s = format (s, "1r3c");
4572   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4573     s = format (s, "2r3c-2698");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4575     s = format (s, "2r3c-4115");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4577     s = format (s, "2r3c-mef5cf1");
4578   else
4579     s = format (s, "ILLEGAL");
4580   return s;
4581 }
4582
4583 static u8 *
4584 format_policer_rate_type (u8 * s, va_list * va)
4585 {
4586   u32 i = va_arg (*va, u32);
4587
4588   if (i == SSE2_QOS_RATE_KBPS)
4589     s = format (s, "kbps");
4590   else if (i == SSE2_QOS_RATE_PPS)
4591     s = format (s, "pps");
4592   else
4593     s = format (s, "ILLEGAL");
4594   return s;
4595 }
4596
4597 static u8 *
4598 format_policer_round_type (u8 * s, va_list * va)
4599 {
4600   u32 i = va_arg (*va, u32);
4601
4602   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4603     s = format (s, "closest");
4604   else if (i == SSE2_QOS_ROUND_TO_UP)
4605     s = format (s, "up");
4606   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4607     s = format (s, "down");
4608   else
4609     s = format (s, "ILLEGAL");
4610   return s;
4611 }
4612
4613 static u8 *
4614 format_policer_action_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_ACTION_DROP)
4619     s = format (s, "drop");
4620   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4621     s = format (s, "transmit");
4622   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4623     s = format (s, "mark-and-transmit");
4624   else
4625     s = format (s, "ILLEGAL");
4626   return s;
4627 }
4628
4629 static u8 *
4630 format_dscp (u8 * s, va_list * va)
4631 {
4632   u32 i = va_arg (*va, u32);
4633   char *t = 0;
4634
4635   switch (i)
4636     {
4637 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4638       foreach_vnet_dscp
4639 #undef _
4640     default:
4641       return format (s, "ILLEGAL");
4642     }
4643   s = format (s, "%s", t);
4644   return s;
4645 }
4646
4647 static void
4648 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4649 {
4650   vat_main_t *vam = &vat_main;
4651   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4652
4653   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4654     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4655   else
4656     conform_dscp_str = format (0, "");
4657
4658   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4659     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4660   else
4661     exceed_dscp_str = format (0, "");
4662
4663   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4664     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4665   else
4666     violate_dscp_str = format (0, "");
4667
4668   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4669          "rate type %U, round type %U, %s rate, %s color-aware, "
4670          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4671          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4672          "conform action %U%s, exceed action %U%s, violate action %U%s",
4673          mp->name,
4674          format_policer_type, mp->type,
4675          ntohl (mp->cir),
4676          ntohl (mp->eir),
4677          clib_net_to_host_u64 (mp->cb),
4678          clib_net_to_host_u64 (mp->eb),
4679          format_policer_rate_type, mp->rate_type,
4680          format_policer_round_type, mp->round_type,
4681          mp->single_rate ? "single" : "dual",
4682          mp->color_aware ? "is" : "not",
4683          ntohl (mp->cir_tokens_per_period),
4684          ntohl (mp->pir_tokens_per_period),
4685          ntohl (mp->scale),
4686          ntohl (mp->current_limit),
4687          ntohl (mp->current_bucket),
4688          ntohl (mp->extended_limit),
4689          ntohl (mp->extended_bucket),
4690          clib_net_to_host_u64 (mp->last_update_time),
4691          format_policer_action_type, mp->conform_action_type,
4692          conform_dscp_str,
4693          format_policer_action_type, mp->exceed_action_type,
4694          exceed_dscp_str,
4695          format_policer_action_type, mp->violate_action_type,
4696          violate_dscp_str);
4697
4698   vec_free (conform_dscp_str);
4699   vec_free (exceed_dscp_str);
4700   vec_free (violate_dscp_str);
4701 }
4702
4703 static void vl_api_policer_details_t_handler_json
4704   (vl_api_policer_details_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t *node;
4708   u8 *rate_type_str, *round_type_str, *type_str;
4709   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4710
4711   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4712   round_type_str =
4713     format (0, "%U", format_policer_round_type, mp->round_type);
4714   type_str = format (0, "%U", format_policer_type, mp->type);
4715   conform_action_str = format (0, "%U", format_policer_action_type,
4716                                mp->conform_action_type);
4717   exceed_action_str = format (0, "%U", format_policer_action_type,
4718                               mp->exceed_action_type);
4719   violate_action_str = format (0, "%U", format_policer_action_type,
4720                                mp->violate_action_type);
4721
4722   if (VAT_JSON_ARRAY != vam->json_tree.type)
4723     {
4724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4725       vat_json_init_array (&vam->json_tree);
4726     }
4727   node = vat_json_array_add (&vam->json_tree);
4728
4729   vat_json_init_object (node);
4730   vat_json_object_add_string_copy (node, "name", mp->name);
4731   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4732   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4733   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4734   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4735   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4736   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4737   vat_json_object_add_string_copy (node, "type", type_str);
4738   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4739   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4740   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4741   vat_json_object_add_uint (node, "cir_tokens_per_period",
4742                             ntohl (mp->cir_tokens_per_period));
4743   vat_json_object_add_uint (node, "eir_tokens_per_period",
4744                             ntohl (mp->pir_tokens_per_period));
4745   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4746   vat_json_object_add_uint (node, "current_bucket",
4747                             ntohl (mp->current_bucket));
4748   vat_json_object_add_uint (node, "extended_limit",
4749                             ntohl (mp->extended_limit));
4750   vat_json_object_add_uint (node, "extended_bucket",
4751                             ntohl (mp->extended_bucket));
4752   vat_json_object_add_uint (node, "last_update_time",
4753                             ntohl (mp->last_update_time));
4754   vat_json_object_add_string_copy (node, "conform_action",
4755                                    conform_action_str);
4756   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4757     {
4758       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4759       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4760       vec_free (dscp_str);
4761     }
4762   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4763   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4764     {
4765       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4766       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4767       vec_free (dscp_str);
4768     }
4769   vat_json_object_add_string_copy (node, "violate_action",
4770                                    violate_action_str);
4771   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4772     {
4773       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4774       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4775       vec_free (dscp_str);
4776     }
4777
4778   vec_free (rate_type_str);
4779   vec_free (round_type_str);
4780   vec_free (type_str);
4781   vec_free (conform_action_str);
4782   vec_free (exceed_action_str);
4783   vec_free (violate_action_str);
4784 }
4785
4786 static void
4787 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4788                                            mp)
4789 {
4790   vat_main_t *vam = &vat_main;
4791   int i, count = ntohl (mp->count);
4792
4793   if (count > 0)
4794     print (vam->ofp, "classify table ids (%d) : ", count);
4795   for (i = 0; i < count; i++)
4796     {
4797       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4798       print (vam->ofp, (i < count - 1) ? "," : "");
4799     }
4800   vam->retval = ntohl (mp->retval);
4801   vam->result_ready = 1;
4802 }
4803
4804 static void
4805   vl_api_classify_table_ids_reply_t_handler_json
4806   (vl_api_classify_table_ids_reply_t * mp)
4807 {
4808   vat_main_t *vam = &vat_main;
4809   int i, count = ntohl (mp->count);
4810
4811   if (count > 0)
4812     {
4813       vat_json_node_t node;
4814
4815       vat_json_init_object (&node);
4816       for (i = 0; i < count; i++)
4817         {
4818           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4819         }
4820       vat_json_print (vam->ofp, &node);
4821       vat_json_free (&node);
4822     }
4823   vam->retval = ntohl (mp->retval);
4824   vam->result_ready = 1;
4825 }
4826
4827 static void
4828   vl_api_classify_table_by_interface_reply_t_handler
4829   (vl_api_classify_table_by_interface_reply_t * mp)
4830 {
4831   vat_main_t *vam = &vat_main;
4832   u32 table_id;
4833
4834   table_id = ntohl (mp->l2_table_id);
4835   if (table_id != ~0)
4836     print (vam->ofp, "l2 table id : %d", table_id);
4837   else
4838     print (vam->ofp, "l2 table id : No input ACL tables configured");
4839   table_id = ntohl (mp->ip4_table_id);
4840   if (table_id != ~0)
4841     print (vam->ofp, "ip4 table id : %d", table_id);
4842   else
4843     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4844   table_id = ntohl (mp->ip6_table_id);
4845   if (table_id != ~0)
4846     print (vam->ofp, "ip6 table id : %d", table_id);
4847   else
4848     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4849   vam->retval = ntohl (mp->retval);
4850   vam->result_ready = 1;
4851 }
4852
4853 static void
4854   vl_api_classify_table_by_interface_reply_t_handler_json
4855   (vl_api_classify_table_by_interface_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   vat_json_node_t node;
4859
4860   vat_json_init_object (&node);
4861
4862   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4863   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4864   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4865
4866   vat_json_print (vam->ofp, &node);
4867   vat_json_free (&node);
4868
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void vl_api_policer_add_del_reply_t_handler
4874   (vl_api_policer_add_del_reply_t * mp)
4875 {
4876   vat_main_t *vam = &vat_main;
4877   i32 retval = ntohl (mp->retval);
4878   if (vam->async_mode)
4879     {
4880       vam->async_errors += (retval < 0);
4881     }
4882   else
4883     {
4884       vam->retval = retval;
4885       vam->result_ready = 1;
4886       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4887         /*
4888          * Note: this is just barely thread-safe, depends on
4889          * the main thread spinning waiting for an answer...
4890          */
4891         errmsg ("policer index %d", ntohl (mp->policer_index));
4892     }
4893 }
4894
4895 static void vl_api_policer_add_del_reply_t_handler_json
4896   (vl_api_policer_add_del_reply_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899   vat_json_node_t node;
4900
4901   vat_json_init_object (&node);
4902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4903   vat_json_object_add_uint (&node, "policer_index",
4904                             ntohl (mp->policer_index));
4905
4906   vat_json_print (vam->ofp, &node);
4907   vat_json_free (&node);
4908
4909   vam->retval = ntohl (mp->retval);
4910   vam->result_ready = 1;
4911 }
4912
4913 /* Format hex dump. */
4914 u8 *
4915 format_hex_bytes (u8 * s, va_list * va)
4916 {
4917   u8 *bytes = va_arg (*va, u8 *);
4918   int n_bytes = va_arg (*va, int);
4919   uword i;
4920
4921   /* Print short or long form depending on byte count. */
4922   uword short_form = n_bytes <= 32;
4923   u32 indent = format_get_indent (s);
4924
4925   if (n_bytes == 0)
4926     return s;
4927
4928   for (i = 0; i < n_bytes; i++)
4929     {
4930       if (!short_form && (i % 32) == 0)
4931         s = format (s, "%08x: ", i);
4932       s = format (s, "%02x", bytes[i]);
4933       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4934         s = format (s, "\n%U", format_white_space, indent);
4935     }
4936
4937   return s;
4938 }
4939
4940 static void
4941 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4942                                             * mp)
4943 {
4944   vat_main_t *vam = &vat_main;
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       print (vam->ofp, "classify table info :");
4949       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4950              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4951              ntohl (mp->miss_next_index));
4952       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4953              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4954              ntohl (mp->match_n_vectors));
4955       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4956              ntohl (mp->mask_length));
4957     }
4958   vam->retval = retval;
4959   vam->result_ready = 1;
4960 }
4961
4962 static void
4963   vl_api_classify_table_info_reply_t_handler_json
4964   (vl_api_classify_table_info_reply_t * mp)
4965 {
4966   vat_main_t *vam = &vat_main;
4967   vat_json_node_t node;
4968
4969   i32 retval = ntohl (mp->retval);
4970   if (retval == 0)
4971     {
4972       vat_json_init_object (&node);
4973
4974       vat_json_object_add_int (&node, "sessions",
4975                                ntohl (mp->active_sessions));
4976       vat_json_object_add_int (&node, "nexttbl",
4977                                ntohl (mp->next_table_index));
4978       vat_json_object_add_int (&node, "nextnode",
4979                                ntohl (mp->miss_next_index));
4980       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4981       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4982       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4983       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4984                       ntohl (mp->mask_length), 0);
4985       vat_json_object_add_string_copy (&node, "mask", s);
4986
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4996                                            mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999
5000   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5001          ntohl (mp->hit_next_index), ntohl (mp->advance),
5002          ntohl (mp->opaque_index));
5003   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5004          ntohl (mp->match_length));
5005 }
5006
5007 static void
5008   vl_api_classify_session_details_t_handler_json
5009   (vl_api_classify_session_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node = NULL;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5023   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5024   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5025   u8 *s =
5026     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5027             0);
5028   vat_json_object_add_string_copy (node, "match", s);
5029 }
5030
5031 static void vl_api_pg_create_interface_reply_t_handler
5032   (vl_api_pg_create_interface_reply_t * mp)
5033 {
5034   vat_main_t *vam = &vat_main;
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_pg_create_interface_reply_t_handler_json
5041   (vl_api_pg_create_interface_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   vat_json_node_t node;
5045
5046   i32 retval = ntohl (mp->retval);
5047   if (retval == 0)
5048     {
5049       vat_json_init_object (&node);
5050
5051       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5052
5053       vat_json_print (vam->ofp, &node);
5054       vat_json_free (&node);
5055     }
5056   vam->retval = ntohl (mp->retval);
5057   vam->result_ready = 1;
5058 }
5059
5060 static void vl_api_policer_classify_details_t_handler
5061   (vl_api_policer_classify_details_t * mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064
5065   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5066          ntohl (mp->table_index));
5067 }
5068
5069 static void vl_api_policer_classify_details_t_handler_json
5070   (vl_api_policer_classify_details_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   vat_json_node_t *node;
5074
5075   if (VAT_JSON_ARRAY != vam->json_tree.type)
5076     {
5077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5078       vat_json_init_array (&vam->json_tree);
5079     }
5080   node = vat_json_array_add (&vam->json_tree);
5081
5082   vat_json_init_object (node);
5083   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5084   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5085 }
5086
5087 static void vl_api_flow_classify_details_t_handler
5088   (vl_api_flow_classify_details_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091
5092   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5093          ntohl (mp->table_index));
5094 }
5095
5096 static void vl_api_flow_classify_details_t_handler_json
5097   (vl_api_flow_classify_details_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100   vat_json_node_t *node;
5101
5102   if (VAT_JSON_ARRAY != vam->json_tree.type)
5103     {
5104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5105       vat_json_init_array (&vam->json_tree);
5106     }
5107   node = vat_json_array_add (&vam->json_tree);
5108
5109   vat_json_init_object (node);
5110   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5111   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5112 }
5113
5114 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5115 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5116 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5117 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5118 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5119 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5121 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5122 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5123 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5124
5125 /*
5126  * Generate boilerplate reply handlers, which
5127  * dig the return value out of the xxx_reply_t API message,
5128  * stick it into vam->retval, and set vam->result_ready
5129  *
5130  * Could also do this by pointing N message decode slots at
5131  * a single function, but that could break in subtle ways.
5132  */
5133
5134 #define foreach_standard_reply_retval_handler           \
5135 _(sw_interface_set_flags_reply)                         \
5136 _(sw_interface_add_del_address_reply)                   \
5137 _(sw_interface_set_rx_mode_reply)                       \
5138 _(sw_interface_set_rx_placement_reply)                  \
5139 _(sw_interface_set_table_reply)                         \
5140 _(sw_interface_set_mpls_enable_reply)                   \
5141 _(sw_interface_set_vpath_reply)                         \
5142 _(sw_interface_set_vxlan_bypass_reply)                  \
5143 _(sw_interface_set_geneve_bypass_reply)                 \
5144 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5145 _(sw_interface_set_l2_bridge_reply)                     \
5146 _(bridge_domain_add_del_reply)                          \
5147 _(sw_interface_set_l2_xconnect_reply)                   \
5148 _(l2fib_add_del_reply)                                  \
5149 _(l2fib_flush_int_reply)                                \
5150 _(l2fib_flush_bd_reply)                                 \
5151 _(ip_route_add_del_reply)                               \
5152 _(ip_table_add_del_reply)                               \
5153 _(ip_mroute_add_del_reply)                              \
5154 _(mpls_route_add_del_reply)                             \
5155 _(mpls_table_add_del_reply)                             \
5156 _(mpls_ip_bind_unbind_reply)                            \
5157 _(bier_route_add_del_reply)                             \
5158 _(bier_table_add_del_reply)                             \
5159 _(proxy_arp_add_del_reply)                              \
5160 _(proxy_arp_intfc_enable_disable_reply)                 \
5161 _(sw_interface_set_unnumbered_reply)                    \
5162 _(ip_neighbor_add_del_reply)                            \
5163 _(reset_fib_reply)                                      \
5164 _(dhcp_proxy_config_reply)                              \
5165 _(dhcp_proxy_set_vss_reply)                             \
5166 _(dhcp_client_config_reply)                             \
5167 _(set_ip_flow_hash_reply)                               \
5168 _(sw_interface_ip6_enable_disable_reply)                \
5169 _(ip6nd_proxy_add_del_reply)                            \
5170 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5171 _(sw_interface_ip6nd_ra_config_reply)                   \
5172 _(set_arp_neighbor_limit_reply)                         \
5173 _(l2_patch_add_del_reply)                               \
5174 _(sr_mpls_policy_add_reply)                             \
5175 _(sr_mpls_policy_mod_reply)                             \
5176 _(sr_mpls_policy_del_reply)                             \
5177 _(sr_policy_add_reply)                                  \
5178 _(sr_policy_mod_reply)                                  \
5179 _(sr_policy_del_reply)                                  \
5180 _(sr_localsid_add_del_reply)                            \
5181 _(sr_steering_add_del_reply)                            \
5182 _(classify_add_del_session_reply)                       \
5183 _(classify_set_interface_ip_table_reply)                \
5184 _(classify_set_interface_l2_tables_reply)               \
5185 _(l2tpv3_set_tunnel_cookies_reply)                      \
5186 _(l2tpv3_interface_enable_disable_reply)                \
5187 _(l2tpv3_set_lookup_key_reply)                          \
5188 _(l2_fib_clear_table_reply)                             \
5189 _(l2_interface_efp_filter_reply)                        \
5190 _(l2_interface_vlan_tag_rewrite_reply)                  \
5191 _(modify_vhost_user_if_reply)                           \
5192 _(delete_vhost_user_if_reply)                           \
5193 _(ip_probe_neighbor_reply)                              \
5194 _(ip_scan_neighbor_enable_disable_reply)                \
5195 _(want_ip4_arp_events_reply)                            \
5196 _(want_ip6_nd_events_reply)                             \
5197 _(want_l2_macs_events_reply)                            \
5198 _(input_acl_set_interface_reply)                        \
5199 _(ipsec_spd_add_del_reply)                              \
5200 _(ipsec_interface_add_del_spd_reply)                    \
5201 _(ipsec_spd_entry_add_del_reply)                        \
5202 _(ipsec_sad_entry_add_del_reply)                        \
5203 _(ipsec_tunnel_if_add_del_reply)                        \
5204 _(ipsec_tunnel_if_set_sa_reply)                         \
5205 _(delete_loopback_reply)                                \
5206 _(bd_ip_mac_add_del_reply)                              \
5207 _(bd_ip_mac_flush_reply)                                \
5208 _(want_interface_events_reply)                          \
5209 _(cop_interface_enable_disable_reply)                   \
5210 _(cop_whitelist_enable_disable_reply)                   \
5211 _(sw_interface_clear_stats_reply)                       \
5212 _(ioam_enable_reply)                                    \
5213 _(ioam_disable_reply)                                   \
5214 _(one_add_del_locator_reply)                            \
5215 _(one_add_del_local_eid_reply)                          \
5216 _(one_add_del_remote_mapping_reply)                     \
5217 _(one_add_del_adjacency_reply)                          \
5218 _(one_add_del_map_resolver_reply)                       \
5219 _(one_add_del_map_server_reply)                         \
5220 _(one_enable_disable_reply)                             \
5221 _(one_rloc_probe_enable_disable_reply)                  \
5222 _(one_map_register_enable_disable_reply)                \
5223 _(one_map_register_set_ttl_reply)                       \
5224 _(one_set_transport_protocol_reply)                     \
5225 _(one_map_register_fallback_threshold_reply)            \
5226 _(one_pitr_set_locator_set_reply)                       \
5227 _(one_map_request_mode_reply)                           \
5228 _(one_add_del_map_request_itr_rlocs_reply)              \
5229 _(one_eid_table_add_del_map_reply)                      \
5230 _(one_use_petr_reply)                                   \
5231 _(one_stats_enable_disable_reply)                       \
5232 _(one_add_del_l2_arp_entry_reply)                       \
5233 _(one_add_del_ndp_entry_reply)                          \
5234 _(one_stats_flush_reply)                                \
5235 _(one_enable_disable_xtr_mode_reply)                    \
5236 _(one_enable_disable_pitr_mode_reply)                   \
5237 _(one_enable_disable_petr_mode_reply)                   \
5238 _(gpe_enable_disable_reply)                             \
5239 _(gpe_set_encap_mode_reply)                             \
5240 _(gpe_add_del_iface_reply)                              \
5241 _(gpe_add_del_native_fwd_rpath_reply)                   \
5242 _(af_packet_delete_reply)                               \
5243 _(policer_classify_set_interface_reply)                 \
5244 _(netmap_create_reply)                                  \
5245 _(netmap_delete_reply)                                  \
5246 _(set_ipfix_exporter_reply)                             \
5247 _(set_ipfix_classify_stream_reply)                      \
5248 _(ipfix_classify_table_add_del_reply)                   \
5249 _(flow_classify_set_interface_reply)                    \
5250 _(sw_interface_span_enable_disable_reply)               \
5251 _(pg_capture_reply)                                     \
5252 _(pg_enable_disable_reply)                              \
5253 _(ip_source_and_port_range_check_add_del_reply)         \
5254 _(ip_source_and_port_range_check_interface_add_del_reply)\
5255 _(delete_subif_reply)                                   \
5256 _(l2_interface_pbb_tag_rewrite_reply)                   \
5257 _(set_punt_reply)                                       \
5258 _(feature_enable_disable_reply)                         \
5259 _(sw_interface_tag_add_del_reply)                       \
5260 _(hw_interface_set_mtu_reply)                           \
5261 _(p2p_ethernet_add_reply)                               \
5262 _(p2p_ethernet_del_reply)                               \
5263 _(lldp_config_reply)                                    \
5264 _(sw_interface_set_lldp_reply)                          \
5265 _(tcp_configure_src_addresses_reply)                    \
5266 _(dns_enable_disable_reply)                             \
5267 _(dns_name_server_add_del_reply)                        \
5268 _(session_rule_add_del_reply)                           \
5269 _(ip_container_proxy_add_del_reply)                     \
5270 _(output_acl_set_interface_reply)                       \
5271 _(qos_record_enable_disable_reply)
5272
5273 #define _(n)                                    \
5274     static void vl_api_##n##_t_handler          \
5275     (vl_api_##n##_t * mp)                       \
5276     {                                           \
5277         vat_main_t * vam = &vat_main;           \
5278         i32 retval = ntohl(mp->retval);         \
5279         if (vam->async_mode) {                  \
5280             vam->async_errors += (retval < 0);  \
5281         } else {                                \
5282             vam->retval = retval;               \
5283             vam->result_ready = 1;              \
5284         }                                       \
5285     }
5286 foreach_standard_reply_retval_handler;
5287 #undef _
5288
5289 #define _(n)                                    \
5290     static void vl_api_##n##_t_handler_json     \
5291     (vl_api_##n##_t * mp)                       \
5292     {                                           \
5293         vat_main_t * vam = &vat_main;           \
5294         vat_json_node_t node;                   \
5295         vat_json_init_object(&node);            \
5296         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5297         vat_json_print(vam->ofp, &node);        \
5298         vam->retval = ntohl(mp->retval);        \
5299         vam->result_ready = 1;                  \
5300     }
5301 foreach_standard_reply_retval_handler;
5302 #undef _
5303
5304 /*
5305  * Table of message reply handlers, must include boilerplate handlers
5306  * we just generated
5307  */
5308
5309 #define foreach_vpe_api_reply_msg                                       \
5310 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5311 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5312 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5313 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5314 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5315 _(CLI_REPLY, cli_reply)                                                 \
5316 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5317 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5318   sw_interface_add_del_address_reply)                                   \
5319 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5320 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5321 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5322 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5323 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5324 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5325 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5326 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5327 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5328 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5329   sw_interface_set_l2_xconnect_reply)                                   \
5330 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5331   sw_interface_set_l2_bridge_reply)                                     \
5332 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5333 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5334 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5335 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5336 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5337 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5338 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5339 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5340 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5341 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5342 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5343 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5344 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5345 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5346 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5347 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5348 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5349 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5350 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5351 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5352 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5353 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5354 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5355 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5356 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5357 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5358 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5359 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5360 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5361 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5362   proxy_arp_intfc_enable_disable_reply)                                 \
5363 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5364 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5365   sw_interface_set_unnumbered_reply)                                    \
5366 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5367 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5368 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5369 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5370 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5371 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5372 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5373 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5374 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5375 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5376   sw_interface_ip6_enable_disable_reply)                                \
5377 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5378 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5379 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5380   sw_interface_ip6nd_ra_prefix_reply)                                   \
5381 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5382   sw_interface_ip6nd_ra_config_reply)                                   \
5383 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5384 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5385 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5386 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5387 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5388 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5389 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5390 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5391 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5392 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5393 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5394 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5395 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5396 classify_set_interface_ip_table_reply)                                  \
5397 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5398   classify_set_interface_l2_tables_reply)                               \
5399 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5400 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5401 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5402 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5403 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5404   l2tpv3_interface_enable_disable_reply)                                \
5405 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5406 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5407 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5408 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5409 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5410 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5411 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5412 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5413 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5414 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5415 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5416 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5417 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5418 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5419 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5420 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5421 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5422 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5423 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5424 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5425 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5426 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5427 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5428 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5429 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5430 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5431 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5432 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5433 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5434 _(L2_MACS_EVENT, l2_macs_event)                                         \
5435 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5436 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5437 _(IP_DETAILS, ip_details)                                               \
5438 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5439 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5440 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5441 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5442 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5443 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5444 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5445 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5446 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5447 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5448 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5449 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5450 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5451 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5452 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5453 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5454 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5455 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5456 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5457 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5458 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5459 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5460 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5461 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5462 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5463 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5464 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5465 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5466 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5467   one_map_register_enable_disable_reply)                                \
5468 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5469 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5470 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5471 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5472   one_map_register_fallback_threshold_reply)                            \
5473 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5474   one_rloc_probe_enable_disable_reply)                                  \
5475 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5476 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5477 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5478 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5479 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5480 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5481 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5482 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5483 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5484 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5485 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5486 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5487 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5488 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5489 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5490 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5491   show_one_stats_enable_disable_reply)                                  \
5492 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5493 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5494 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5495 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5496 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5497 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5498 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5499 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5500   one_enable_disable_pitr_mode_reply)                                   \
5501 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5502   one_enable_disable_petr_mode_reply)                                   \
5503 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5504 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5505 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5506 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5507 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5508 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5509 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5510 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5511 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5512 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5513 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5514 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5515   gpe_add_del_native_fwd_rpath_reply)                                   \
5516 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5517   gpe_fwd_entry_path_details)                                           \
5518 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5519 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5520   one_add_del_map_request_itr_rlocs_reply)                              \
5521 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5522   one_get_map_request_itr_rlocs_reply)                                  \
5523 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5524 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5525 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5526 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5527 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5528 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5529   show_one_map_register_state_reply)                                    \
5530 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5531 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5532   show_one_map_register_fallback_threshold_reply)                       \
5533 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5534 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5535 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5536 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5537 _(POLICER_DETAILS, policer_details)                                     \
5538 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5539 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5540 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5541 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5542 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5543 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5544 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5545 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5546 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5547 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5548 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5549 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5550 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5551 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5552 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5553 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5554 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5555 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5556 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5557 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5558 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5559 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5560 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5561 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5562 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5563 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5564  ip_source_and_port_range_check_add_del_reply)                          \
5565 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5566  ip_source_and_port_range_check_interface_add_del_reply)                \
5567 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5568 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5569 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5570 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5571 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5572 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5573 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5574 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5575 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5576 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5577 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5578 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5579 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5580 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5581 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5582 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5583 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5584 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5585 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5586 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5587 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5588 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5589 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5590 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5591 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5592 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5593
5594 #define foreach_standalone_reply_msg                                    \
5595 _(SW_INTERFACE_EVENT, sw_interface_event)
5596
5597 typedef struct
5598 {
5599   u8 *name;
5600   u32 value;
5601 } name_sort_t;
5602
5603 #define STR_VTR_OP_CASE(op)     \
5604     case L2_VTR_ ## op:         \
5605         return "" # op;
5606
5607 static const char *
5608 str_vtr_op (u32 vtr_op)
5609 {
5610   switch (vtr_op)
5611     {
5612       STR_VTR_OP_CASE (DISABLED);
5613       STR_VTR_OP_CASE (PUSH_1);
5614       STR_VTR_OP_CASE (PUSH_2);
5615       STR_VTR_OP_CASE (POP_1);
5616       STR_VTR_OP_CASE (POP_2);
5617       STR_VTR_OP_CASE (TRANSLATE_1_1);
5618       STR_VTR_OP_CASE (TRANSLATE_1_2);
5619       STR_VTR_OP_CASE (TRANSLATE_2_1);
5620       STR_VTR_OP_CASE (TRANSLATE_2_2);
5621     }
5622
5623   return "UNKNOWN";
5624 }
5625
5626 static int
5627 dump_sub_interface_table (vat_main_t * vam)
5628 {
5629   const sw_interface_subif_t *sub = NULL;
5630
5631   if (vam->json_output)
5632     {
5633       clib_warning
5634         ("JSON output supported only for VPE API calls and dump_stats_table");
5635       return -99;
5636     }
5637
5638   print (vam->ofp,
5639          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5640          "Interface", "sw_if_index",
5641          "sub id", "dot1ad", "tags", "outer id",
5642          "inner id", "exact", "default", "outer any", "inner any");
5643
5644   vec_foreach (sub, vam->sw_if_subif_table)
5645   {
5646     print (vam->ofp,
5647            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5648            sub->interface_name,
5649            sub->sw_if_index,
5650            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5651            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5652            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5653            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5654     if (sub->vtr_op != L2_VTR_DISABLED)
5655       {
5656         print (vam->ofp,
5657                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5658                "tag1: %d tag2: %d ]",
5659                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5660                sub->vtr_tag1, sub->vtr_tag2);
5661       }
5662   }
5663
5664   return 0;
5665 }
5666
5667 static int
5668 name_sort_cmp (void *a1, void *a2)
5669 {
5670   name_sort_t *n1 = a1;
5671   name_sort_t *n2 = a2;
5672
5673   return strcmp ((char *) n1->name, (char *) n2->name);
5674 }
5675
5676 static int
5677 dump_interface_table (vat_main_t * vam)
5678 {
5679   hash_pair_t *p;
5680   name_sort_t *nses = 0, *ns;
5681
5682   if (vam->json_output)
5683     {
5684       clib_warning
5685         ("JSON output supported only for VPE API calls and dump_stats_table");
5686       return -99;
5687     }
5688
5689   /* *INDENT-OFF* */
5690   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5691   ({
5692     vec_add2 (nses, ns, 1);
5693     ns->name = (u8 *)(p->key);
5694     ns->value = (u32) p->value[0];
5695   }));
5696   /* *INDENT-ON* */
5697
5698   vec_sort_with_function (nses, name_sort_cmp);
5699
5700   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5701   vec_foreach (ns, nses)
5702   {
5703     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5704   }
5705   vec_free (nses);
5706   return 0;
5707 }
5708
5709 static int
5710 dump_ip_table (vat_main_t * vam, int is_ipv6)
5711 {
5712   const ip_details_t *det = NULL;
5713   const ip_address_details_t *address = NULL;
5714   u32 i = ~0;
5715
5716   print (vam->ofp, "%-12s", "sw_if_index");
5717
5718   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5719   {
5720     i++;
5721     if (!det->present)
5722       {
5723         continue;
5724       }
5725     print (vam->ofp, "%-12d", i);
5726     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5727     if (!det->addr)
5728       {
5729         continue;
5730       }
5731     vec_foreach (address, det->addr)
5732     {
5733       print (vam->ofp,
5734              "            %-30U%-13d",
5735              is_ipv6 ? format_ip6_address : format_ip4_address,
5736              address->ip, address->prefix_length);
5737     }
5738   }
5739
5740   return 0;
5741 }
5742
5743 static int
5744 dump_ipv4_table (vat_main_t * vam)
5745 {
5746   if (vam->json_output)
5747     {
5748       clib_warning
5749         ("JSON output supported only for VPE API calls and dump_stats_table");
5750       return -99;
5751     }
5752
5753   return dump_ip_table (vam, 0);
5754 }
5755
5756 static int
5757 dump_ipv6_table (vat_main_t * vam)
5758 {
5759   if (vam->json_output)
5760     {
5761       clib_warning
5762         ("JSON output supported only for VPE API calls and dump_stats_table");
5763       return -99;
5764     }
5765
5766   return dump_ip_table (vam, 1);
5767 }
5768
5769 /*
5770  * Pass CLI buffers directly in the CLI_INBAND API message,
5771  * instead of an additional shared memory area.
5772  */
5773 static int
5774 exec_inband (vat_main_t * vam)
5775 {
5776   vl_api_cli_inband_t *mp;
5777   unformat_input_t *i = vam->input;
5778   int ret;
5779
5780   if (vec_len (i->buffer) == 0)
5781     return -1;
5782
5783   if (vam->exec_mode == 0 && unformat (i, "mode"))
5784     {
5785       vam->exec_mode = 1;
5786       return 0;
5787     }
5788   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5789     {
5790       vam->exec_mode = 0;
5791       return 0;
5792     }
5793
5794   /*
5795    * In order for the CLI command to work, it
5796    * must be a vector ending in \n, not a C-string ending
5797    * in \n\0.
5798    */
5799   u32 len = vec_len (vam->input->buffer);
5800   M2 (CLI_INBAND, mp, len);
5801   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5802
5803   S (mp);
5804   W (ret);
5805   /* json responses may or may not include a useful reply... */
5806   if (vec_len (vam->cmd_reply))
5807     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5808   return ret;
5809 }
5810
5811 int
5812 exec (vat_main_t * vam)
5813 {
5814   return exec_inband (vam);
5815 }
5816
5817 static int
5818 api_create_loopback (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_create_loopback_t *mp;
5822   vl_api_create_loopback_instance_t *mp_lbi;
5823   u8 mac_address[6];
5824   u8 mac_set = 0;
5825   u8 is_specified = 0;
5826   u32 user_instance = 0;
5827   int ret;
5828
5829   clib_memset (mac_address, 0, sizeof (mac_address));
5830
5831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5832     {
5833       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5834         mac_set = 1;
5835       if (unformat (i, "instance %d", &user_instance))
5836         is_specified = 1;
5837       else
5838         break;
5839     }
5840
5841   if (is_specified)
5842     {
5843       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5844       mp_lbi->is_specified = is_specified;
5845       if (is_specified)
5846         mp_lbi->user_instance = htonl (user_instance);
5847       if (mac_set)
5848         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5849       S (mp_lbi);
5850     }
5851   else
5852     {
5853       /* Construct the API message */
5854       M (CREATE_LOOPBACK, mp);
5855       if (mac_set)
5856         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5857       S (mp);
5858     }
5859
5860   W (ret);
5861   return ret;
5862 }
5863
5864 static int
5865 api_delete_loopback (vat_main_t * vam)
5866 {
5867   unformat_input_t *i = vam->input;
5868   vl_api_delete_loopback_t *mp;
5869   u32 sw_if_index = ~0;
5870   int ret;
5871
5872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5873     {
5874       if (unformat (i, "sw_if_index %d", &sw_if_index))
5875         ;
5876       else
5877         break;
5878     }
5879
5880   if (sw_if_index == ~0)
5881     {
5882       errmsg ("missing sw_if_index");
5883       return -99;
5884     }
5885
5886   /* Construct the API message */
5887   M (DELETE_LOOPBACK, mp);
5888   mp->sw_if_index = ntohl (sw_if_index);
5889
5890   S (mp);
5891   W (ret);
5892   return ret;
5893 }
5894
5895 static int
5896 api_want_interface_events (vat_main_t * vam)
5897 {
5898   unformat_input_t *i = vam->input;
5899   vl_api_want_interface_events_t *mp;
5900   int enable = -1;
5901   int ret;
5902
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "enable"))
5906         enable = 1;
5907       else if (unformat (i, "disable"))
5908         enable = 0;
5909       else
5910         break;
5911     }
5912
5913   if (enable == -1)
5914     {
5915       errmsg ("missing enable|disable");
5916       return -99;
5917     }
5918
5919   M (WANT_INTERFACE_EVENTS, mp);
5920   mp->enable_disable = enable;
5921
5922   vam->interface_event_display = enable;
5923
5924   S (mp);
5925   W (ret);
5926   return ret;
5927 }
5928
5929
5930 /* Note: non-static, called once to set up the initial intfc table */
5931 int
5932 api_sw_interface_dump (vat_main_t * vam)
5933 {
5934   vl_api_sw_interface_dump_t *mp;
5935   vl_api_control_ping_t *mp_ping;
5936   hash_pair_t *p;
5937   name_sort_t *nses = 0, *ns;
5938   sw_interface_subif_t *sub = NULL;
5939   int ret;
5940
5941   /* Toss the old name table */
5942   /* *INDENT-OFF* */
5943   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5944   ({
5945     vec_add2 (nses, ns, 1);
5946     ns->name = (u8 *)(p->key);
5947     ns->value = (u32) p->value[0];
5948   }));
5949   /* *INDENT-ON* */
5950
5951   hash_free (vam->sw_if_index_by_interface_name);
5952
5953   vec_foreach (ns, nses) vec_free (ns->name);
5954
5955   vec_free (nses);
5956
5957   vec_foreach (sub, vam->sw_if_subif_table)
5958   {
5959     vec_free (sub->interface_name);
5960   }
5961   vec_free (vam->sw_if_subif_table);
5962
5963   /* recreate the interface name hash table */
5964   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5965
5966   /*
5967    * Ask for all interface names. Otherwise, the epic catalog of
5968    * name filters becomes ridiculously long, and vat ends up needing
5969    * to be taught about new interface types.
5970    */
5971   M (SW_INTERFACE_DUMP, mp);
5972   S (mp);
5973
5974   /* Use a control ping for synchronization */
5975   MPING (CONTROL_PING, mp_ping);
5976   S (mp_ping);
5977
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static int
5983 api_sw_interface_set_flags (vat_main_t * vam)
5984 {
5985   unformat_input_t *i = vam->input;
5986   vl_api_sw_interface_set_flags_t *mp;
5987   u32 sw_if_index;
5988   u8 sw_if_index_set = 0;
5989   u8 admin_up = 0;
5990   int ret;
5991
5992   /* Parse args required to build the message */
5993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5994     {
5995       if (unformat (i, "admin-up"))
5996         admin_up = 1;
5997       else if (unformat (i, "admin-down"))
5998         admin_up = 0;
5999       else
6000         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6001         sw_if_index_set = 1;
6002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6003         sw_if_index_set = 1;
6004       else
6005         break;
6006     }
6007
6008   if (sw_if_index_set == 0)
6009     {
6010       errmsg ("missing interface name or sw_if_index");
6011       return -99;
6012     }
6013
6014   /* Construct the API message */
6015   M (SW_INTERFACE_SET_FLAGS, mp);
6016   mp->sw_if_index = ntohl (sw_if_index);
6017   mp->admin_up_down = admin_up;
6018
6019   /* send it... */
6020   S (mp);
6021
6022   /* Wait for a reply, return the good/bad news... */
6023   W (ret);
6024   return ret;
6025 }
6026
6027 static int
6028 api_sw_interface_set_rx_mode (vat_main_t * vam)
6029 {
6030   unformat_input_t *i = vam->input;
6031   vl_api_sw_interface_set_rx_mode_t *mp;
6032   u32 sw_if_index;
6033   u8 sw_if_index_set = 0;
6034   int ret;
6035   u8 queue_id_valid = 0;
6036   u32 queue_id;
6037   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6038
6039   /* Parse args required to build the message */
6040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6041     {
6042       if (unformat (i, "queue %d", &queue_id))
6043         queue_id_valid = 1;
6044       else if (unformat (i, "polling"))
6045         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6046       else if (unformat (i, "interrupt"))
6047         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6048       else if (unformat (i, "adaptive"))
6049         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6050       else
6051         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6052         sw_if_index_set = 1;
6053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6054         sw_if_index_set = 1;
6055       else
6056         break;
6057     }
6058
6059   if (sw_if_index_set == 0)
6060     {
6061       errmsg ("missing interface name or sw_if_index");
6062       return -99;
6063     }
6064   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6065     {
6066       errmsg ("missing rx-mode");
6067       return -99;
6068     }
6069
6070   /* Construct the API message */
6071   M (SW_INTERFACE_SET_RX_MODE, mp);
6072   mp->sw_if_index = ntohl (sw_if_index);
6073   mp->mode = mode;
6074   mp->queue_id_valid = queue_id_valid;
6075   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6076
6077   /* send it... */
6078   S (mp);
6079
6080   /* Wait for a reply, return the good/bad news... */
6081   W (ret);
6082   return ret;
6083 }
6084
6085 static int
6086 api_sw_interface_set_rx_placement (vat_main_t * vam)
6087 {
6088   unformat_input_t *i = vam->input;
6089   vl_api_sw_interface_set_rx_placement_t *mp;
6090   u32 sw_if_index;
6091   u8 sw_if_index_set = 0;
6092   int ret;
6093   u8 is_main = 0;
6094   u32 queue_id, thread_index;
6095
6096   /* Parse args required to build the message */
6097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6098     {
6099       if (unformat (i, "queue %d", &queue_id))
6100         ;
6101       else if (unformat (i, "main"))
6102         is_main = 1;
6103       else if (unformat (i, "worker %d", &thread_index))
6104         ;
6105       else
6106         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6107         sw_if_index_set = 1;
6108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6109         sw_if_index_set = 1;
6110       else
6111         break;
6112     }
6113
6114   if (sw_if_index_set == 0)
6115     {
6116       errmsg ("missing interface name or sw_if_index");
6117       return -99;
6118     }
6119
6120   if (is_main)
6121     thread_index = 0;
6122   /* Construct the API message */
6123   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6124   mp->sw_if_index = ntohl (sw_if_index);
6125   mp->worker_id = ntohl (thread_index);
6126   mp->queue_id = ntohl (queue_id);
6127   mp->is_main = is_main;
6128
6129   /* send it... */
6130   S (mp);
6131   /* Wait for a reply, return the good/bad news... */
6132   W (ret);
6133   return ret;
6134 }
6135
6136 static void vl_api_sw_interface_rx_placement_details_t_handler
6137   (vl_api_sw_interface_rx_placement_details_t * mp)
6138 {
6139   vat_main_t *vam = &vat_main;
6140   u32 worker_id = ntohl (mp->worker_id);
6141
6142   print (vam->ofp,
6143          "\n%-11d %-11s %-6d %-5d %-9s",
6144          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6145          worker_id, ntohl (mp->queue_id),
6146          (mp->mode ==
6147           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6148 }
6149
6150 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6151   (vl_api_sw_interface_rx_placement_details_t * mp)
6152 {
6153   vat_main_t *vam = &vat_main;
6154   vat_json_node_t *node = NULL;
6155
6156   if (VAT_JSON_ARRAY != vam->json_tree.type)
6157     {
6158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6159       vat_json_init_array (&vam->json_tree);
6160     }
6161   node = vat_json_array_add (&vam->json_tree);
6162
6163   vat_json_init_object (node);
6164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6165   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6166   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6167   vat_json_object_add_uint (node, "mode", mp->mode);
6168 }
6169
6170 static int
6171 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6172 {
6173   unformat_input_t *i = vam->input;
6174   vl_api_sw_interface_rx_placement_dump_t *mp;
6175   vl_api_control_ping_t *mp_ping;
6176   int ret;
6177   u32 sw_if_index;
6178   u8 sw_if_index_set = 0;
6179
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set++;
6184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185         sw_if_index_set++;
6186       else
6187         break;
6188     }
6189
6190   print (vam->ofp,
6191          "\n%-11s %-11s %-6s %-5s %-4s",
6192          "sw_if_index", "main/worker", "thread", "queue", "mode");
6193
6194   /* Dump Interface rx placement */
6195   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6196
6197   if (sw_if_index_set)
6198     mp->sw_if_index = htonl (sw_if_index);
6199   else
6200     mp->sw_if_index = ~0;
6201
6202   S (mp);
6203
6204   /* Use a control ping for synchronization */
6205   MPING (CONTROL_PING, mp_ping);
6206   S (mp_ping);
6207
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_sw_interface_clear_stats (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_sw_interface_clear_stats_t *mp;
6217   u32 sw_if_index;
6218   u8 sw_if_index_set = 0;
6219   int ret;
6220
6221   /* Parse args required to build the message */
6222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6223     {
6224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6225         sw_if_index_set = 1;
6226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6227         sw_if_index_set = 1;
6228       else
6229         break;
6230     }
6231
6232   /* Construct the API message */
6233   M (SW_INTERFACE_CLEAR_STATS, mp);
6234
6235   if (sw_if_index_set == 1)
6236     mp->sw_if_index = ntohl (sw_if_index);
6237   else
6238     mp->sw_if_index = ~0;
6239
6240   /* send it... */
6241   S (mp);
6242
6243   /* Wait for a reply, return the good/bad news... */
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_sw_interface_add_del_address (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_sw_interface_add_del_address_t *mp;
6253   u32 sw_if_index;
6254   u8 sw_if_index_set = 0;
6255   u8 is_add = 1, del_all = 0;
6256   u32 address_length = 0;
6257   u8 v4_address_set = 0;
6258   u8 v6_address_set = 0;
6259   ip4_address_t v4address;
6260   ip6_address_t v6address;
6261   int ret;
6262
6263   /* Parse args required to build the message */
6264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6265     {
6266       if (unformat (i, "del-all"))
6267         del_all = 1;
6268       else if (unformat (i, "del"))
6269         is_add = 0;
6270       else
6271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6272         sw_if_index_set = 1;
6273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6274         sw_if_index_set = 1;
6275       else if (unformat (i, "%U/%d",
6276                          unformat_ip4_address, &v4address, &address_length))
6277         v4_address_set = 1;
6278       else if (unformat (i, "%U/%d",
6279                          unformat_ip6_address, &v6address, &address_length))
6280         v6_address_set = 1;
6281       else
6282         break;
6283     }
6284
6285   if (sw_if_index_set == 0)
6286     {
6287       errmsg ("missing interface name or sw_if_index");
6288       return -99;
6289     }
6290   if (v4_address_set && v6_address_set)
6291     {
6292       errmsg ("both v4 and v6 addresses set");
6293       return -99;
6294     }
6295   if (!v4_address_set && !v6_address_set && !del_all)
6296     {
6297       errmsg ("no addresses set");
6298       return -99;
6299     }
6300
6301   /* Construct the API message */
6302   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6303
6304   mp->sw_if_index = ntohl (sw_if_index);
6305   mp->is_add = is_add;
6306   mp->del_all = del_all;
6307   if (v6_address_set)
6308     {
6309       mp->is_ipv6 = 1;
6310       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6311     }
6312   else
6313     {
6314       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6315     }
6316   mp->address_length = address_length;
6317
6318   /* send it... */
6319   S (mp);
6320
6321   /* Wait for a reply, return good/bad news  */
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static int
6327 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6328 {
6329   unformat_input_t *i = vam->input;
6330   vl_api_sw_interface_set_mpls_enable_t *mp;
6331   u32 sw_if_index;
6332   u8 sw_if_index_set = 0;
6333   u8 enable = 1;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "disable"))
6344         enable = 0;
6345       else if (unformat (i, "dis"))
6346         enable = 0;
6347       else
6348         break;
6349     }
6350
6351   if (sw_if_index_set == 0)
6352     {
6353       errmsg ("missing interface name or sw_if_index");
6354       return -99;
6355     }
6356
6357   /* Construct the API message */
6358   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6359
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   mp->enable = enable;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_sw_interface_set_table (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_sw_interface_set_table_t *mp;
6376   u32 sw_if_index, vrf_id = 0;
6377   u8 sw_if_index_set = 0;
6378   u8 is_ipv6 = 0;
6379   int ret;
6380
6381   /* Parse args required to build the message */
6382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6383     {
6384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6385         sw_if_index_set = 1;
6386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6387         sw_if_index_set = 1;
6388       else if (unformat (i, "vrf %d", &vrf_id))
6389         ;
6390       else if (unformat (i, "ipv6"))
6391         is_ipv6 = 1;
6392       else
6393         break;
6394     }
6395
6396   if (sw_if_index_set == 0)
6397     {
6398       errmsg ("missing interface name or sw_if_index");
6399       return -99;
6400     }
6401
6402   /* Construct the API message */
6403   M (SW_INTERFACE_SET_TABLE, mp);
6404
6405   mp->sw_if_index = ntohl (sw_if_index);
6406   mp->is_ipv6 = is_ipv6;
6407   mp->vrf_id = ntohl (vrf_id);
6408
6409   /* send it... */
6410   S (mp);
6411
6412   /* Wait for a reply... */
6413   W (ret);
6414   return ret;
6415 }
6416
6417 static void vl_api_sw_interface_get_table_reply_t_handler
6418   (vl_api_sw_interface_get_table_reply_t * mp)
6419 {
6420   vat_main_t *vam = &vat_main;
6421
6422   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6423
6424   vam->retval = ntohl (mp->retval);
6425   vam->result_ready = 1;
6426
6427 }
6428
6429 static void vl_api_sw_interface_get_table_reply_t_handler_json
6430   (vl_api_sw_interface_get_table_reply_t * mp)
6431 {
6432   vat_main_t *vam = &vat_main;
6433   vat_json_node_t node;
6434
6435   vat_json_init_object (&node);
6436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6437   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6438
6439   vat_json_print (vam->ofp, &node);
6440   vat_json_free (&node);
6441
6442   vam->retval = ntohl (mp->retval);
6443   vam->result_ready = 1;
6444 }
6445
6446 static int
6447 api_sw_interface_get_table (vat_main_t * vam)
6448 {
6449   unformat_input_t *i = vam->input;
6450   vl_api_sw_interface_get_table_t *mp;
6451   u32 sw_if_index;
6452   u8 sw_if_index_set = 0;
6453   u8 is_ipv6 = 0;
6454   int ret;
6455
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6459         sw_if_index_set = 1;
6460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6461         sw_if_index_set = 1;
6462       else if (unformat (i, "ipv6"))
6463         is_ipv6 = 1;
6464       else
6465         break;
6466     }
6467
6468   if (sw_if_index_set == 0)
6469     {
6470       errmsg ("missing interface name or sw_if_index");
6471       return -99;
6472     }
6473
6474   M (SW_INTERFACE_GET_TABLE, mp);
6475   mp->sw_if_index = htonl (sw_if_index);
6476   mp->is_ipv6 = is_ipv6;
6477
6478   S (mp);
6479   W (ret);
6480   return ret;
6481 }
6482
6483 static int
6484 api_sw_interface_set_vpath (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_sw_interface_set_vpath_t *mp;
6488   u32 sw_if_index = 0;
6489   u8 sw_if_index_set = 0;
6490   u8 is_enable = 0;
6491   int ret;
6492
6493   /* Parse args required to build the message */
6494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6495     {
6496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6497         sw_if_index_set = 1;
6498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6499         sw_if_index_set = 1;
6500       else if (unformat (i, "enable"))
6501         is_enable = 1;
6502       else if (unformat (i, "disable"))
6503         is_enable = 0;
6504       else
6505         break;
6506     }
6507
6508   if (sw_if_index_set == 0)
6509     {
6510       errmsg ("missing interface name or sw_if_index");
6511       return -99;
6512     }
6513
6514   /* Construct the API message */
6515   M (SW_INTERFACE_SET_VPATH, mp);
6516
6517   mp->sw_if_index = ntohl (sw_if_index);
6518   mp->enable = is_enable;
6519
6520   /* send it... */
6521   S (mp);
6522
6523   /* Wait for a reply... */
6524   W (ret);
6525   return ret;
6526 }
6527
6528 static int
6529 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6530 {
6531   unformat_input_t *i = vam->input;
6532   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6533   u32 sw_if_index = 0;
6534   u8 sw_if_index_set = 0;
6535   u8 is_enable = 1;
6536   u8 is_ipv6 = 0;
6537   int ret;
6538
6539   /* Parse args required to build the message */
6540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6541     {
6542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6543         sw_if_index_set = 1;
6544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "enable"))
6547         is_enable = 1;
6548       else if (unformat (i, "disable"))
6549         is_enable = 0;
6550       else if (unformat (i, "ip4"))
6551         is_ipv6 = 0;
6552       else if (unformat (i, "ip6"))
6553         is_ipv6 = 1;
6554       else
6555         break;
6556     }
6557
6558   if (sw_if_index_set == 0)
6559     {
6560       errmsg ("missing interface name or sw_if_index");
6561       return -99;
6562     }
6563
6564   /* Construct the API message */
6565   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6566
6567   mp->sw_if_index = ntohl (sw_if_index);
6568   mp->enable = is_enable;
6569   mp->is_ipv6 = is_ipv6;
6570
6571   /* send it... */
6572   S (mp);
6573
6574   /* Wait for a reply... */
6575   W (ret);
6576   return ret;
6577 }
6578
6579 static int
6580 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6581 {
6582   unformat_input_t *i = vam->input;
6583   vl_api_sw_interface_set_geneve_bypass_t *mp;
6584   u32 sw_if_index = 0;
6585   u8 sw_if_index_set = 0;
6586   u8 is_enable = 1;
6587   u8 is_ipv6 = 0;
6588   int ret;
6589
6590   /* Parse args required to build the message */
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "enable"))
6598         is_enable = 1;
6599       else if (unformat (i, "disable"))
6600         is_enable = 0;
6601       else if (unformat (i, "ip4"))
6602         is_ipv6 = 0;
6603       else if (unformat (i, "ip6"))
6604         is_ipv6 = 1;
6605       else
6606         break;
6607     }
6608
6609   if (sw_if_index_set == 0)
6610     {
6611       errmsg ("missing interface name or sw_if_index");
6612       return -99;
6613     }
6614
6615   /* Construct the API message */
6616   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6617
6618   mp->sw_if_index = ntohl (sw_if_index);
6619   mp->enable = is_enable;
6620   mp->is_ipv6 = is_ipv6;
6621
6622   /* send it... */
6623   S (mp);
6624
6625   /* Wait for a reply... */
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_sw_interface_set_l2_xconnect_t *mp;
6635   u32 rx_sw_if_index;
6636   u8 rx_sw_if_index_set = 0;
6637   u32 tx_sw_if_index;
6638   u8 tx_sw_if_index_set = 0;
6639   u8 enable = 1;
6640   int ret;
6641
6642   /* Parse args required to build the message */
6643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644     {
6645       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6646         rx_sw_if_index_set = 1;
6647       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6648         tx_sw_if_index_set = 1;
6649       else if (unformat (i, "rx"))
6650         {
6651           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6652             {
6653               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6654                             &rx_sw_if_index))
6655                 rx_sw_if_index_set = 1;
6656             }
6657           else
6658             break;
6659         }
6660       else if (unformat (i, "tx"))
6661         {
6662           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663             {
6664               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6665                             &tx_sw_if_index))
6666                 tx_sw_if_index_set = 1;
6667             }
6668           else
6669             break;
6670         }
6671       else if (unformat (i, "enable"))
6672         enable = 1;
6673       else if (unformat (i, "disable"))
6674         enable = 0;
6675       else
6676         break;
6677     }
6678
6679   if (rx_sw_if_index_set == 0)
6680     {
6681       errmsg ("missing rx interface name or rx_sw_if_index");
6682       return -99;
6683     }
6684
6685   if (enable && (tx_sw_if_index_set == 0))
6686     {
6687       errmsg ("missing tx interface name or tx_sw_if_index");
6688       return -99;
6689     }
6690
6691   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6692
6693   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6694   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6695   mp->enable = enable;
6696
6697   S (mp);
6698   W (ret);
6699   return ret;
6700 }
6701
6702 static int
6703 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6704 {
6705   unformat_input_t *i = vam->input;
6706   vl_api_sw_interface_set_l2_bridge_t *mp;
6707   vl_api_l2_port_type_t port_type;
6708   u32 rx_sw_if_index;
6709   u8 rx_sw_if_index_set = 0;
6710   u32 bd_id;
6711   u8 bd_id_set = 0;
6712   u32 shg = 0;
6713   u8 enable = 1;
6714   int ret;
6715
6716   port_type = L2_API_PORT_TYPE_NORMAL;
6717
6718   /* Parse args required to build the message */
6719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6720     {
6721       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6722         rx_sw_if_index_set = 1;
6723       else if (unformat (i, "bd_id %d", &bd_id))
6724         bd_id_set = 1;
6725       else
6726         if (unformat
6727             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6728         rx_sw_if_index_set = 1;
6729       else if (unformat (i, "shg %d", &shg))
6730         ;
6731       else if (unformat (i, "bvi"))
6732         port_type = L2_API_PORT_TYPE_BVI;
6733       else if (unformat (i, "uu-fwd"))
6734         port_type = L2_API_PORT_TYPE_UU_FWD;
6735       else if (unformat (i, "enable"))
6736         enable = 1;
6737       else if (unformat (i, "disable"))
6738         enable = 0;
6739       else
6740         break;
6741     }
6742
6743   if (rx_sw_if_index_set == 0)
6744     {
6745       errmsg ("missing rx interface name or sw_if_index");
6746       return -99;
6747     }
6748
6749   if (enable && (bd_id_set == 0))
6750     {
6751       errmsg ("missing bridge domain");
6752       return -99;
6753     }
6754
6755   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6756
6757   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6758   mp->bd_id = ntohl (bd_id);
6759   mp->shg = (u8) shg;
6760   mp->port_type = ntohl (port_type);
6761   mp->enable = enable;
6762
6763   S (mp);
6764   W (ret);
6765   return ret;
6766 }
6767
6768 static int
6769 api_bridge_domain_dump (vat_main_t * vam)
6770 {
6771   unformat_input_t *i = vam->input;
6772   vl_api_bridge_domain_dump_t *mp;
6773   vl_api_control_ping_t *mp_ping;
6774   u32 bd_id = ~0;
6775   int ret;
6776
6777   /* Parse args required to build the message */
6778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6779     {
6780       if (unformat (i, "bd_id %d", &bd_id))
6781         ;
6782       else
6783         break;
6784     }
6785
6786   M (BRIDGE_DOMAIN_DUMP, mp);
6787   mp->bd_id = ntohl (bd_id);
6788   S (mp);
6789
6790   /* Use a control ping for synchronization */
6791   MPING (CONTROL_PING, mp_ping);
6792   S (mp_ping);
6793
6794   W (ret);
6795   return ret;
6796 }
6797
6798 static int
6799 api_bridge_domain_add_del (vat_main_t * vam)
6800 {
6801   unformat_input_t *i = vam->input;
6802   vl_api_bridge_domain_add_del_t *mp;
6803   u32 bd_id = ~0;
6804   u8 is_add = 1;
6805   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6806   u8 *bd_tag = NULL;
6807   u32 mac_age = 0;
6808   int ret;
6809
6810   /* Parse args required to build the message */
6811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6812     {
6813       if (unformat (i, "bd_id %d", &bd_id))
6814         ;
6815       else if (unformat (i, "flood %d", &flood))
6816         ;
6817       else if (unformat (i, "uu-flood %d", &uu_flood))
6818         ;
6819       else if (unformat (i, "forward %d", &forward))
6820         ;
6821       else if (unformat (i, "learn %d", &learn))
6822         ;
6823       else if (unformat (i, "arp-term %d", &arp_term))
6824         ;
6825       else if (unformat (i, "mac-age %d", &mac_age))
6826         ;
6827       else if (unformat (i, "bd-tag %s", &bd_tag))
6828         ;
6829       else if (unformat (i, "del"))
6830         {
6831           is_add = 0;
6832           flood = uu_flood = forward = learn = 0;
6833         }
6834       else
6835         break;
6836     }
6837
6838   if (bd_id == ~0)
6839     {
6840       errmsg ("missing bridge domain");
6841       ret = -99;
6842       goto done;
6843     }
6844
6845   if (mac_age > 255)
6846     {
6847       errmsg ("mac age must be less than 256 ");
6848       ret = -99;
6849       goto done;
6850     }
6851
6852   if ((bd_tag) && (vec_len (bd_tag) > 63))
6853     {
6854       errmsg ("bd-tag cannot be longer than 63");
6855       ret = -99;
6856       goto done;
6857     }
6858
6859   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6860
6861   mp->bd_id = ntohl (bd_id);
6862   mp->flood = flood;
6863   mp->uu_flood = uu_flood;
6864   mp->forward = forward;
6865   mp->learn = learn;
6866   mp->arp_term = arp_term;
6867   mp->is_add = is_add;
6868   mp->mac_age = (u8) mac_age;
6869   if (bd_tag)
6870     {
6871       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6872       mp->bd_tag[vec_len (bd_tag)] = 0;
6873     }
6874   S (mp);
6875   W (ret);
6876
6877 done:
6878   vec_free (bd_tag);
6879   return ret;
6880 }
6881
6882 static int
6883 api_l2fib_flush_bd (vat_main_t * vam)
6884 {
6885   unformat_input_t *i = vam->input;
6886   vl_api_l2fib_flush_bd_t *mp;
6887   u32 bd_id = ~0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "bd_id %d", &bd_id));
6894       else
6895         break;
6896     }
6897
6898   if (bd_id == ~0)
6899     {
6900       errmsg ("missing bridge domain");
6901       return -99;
6902     }
6903
6904   M (L2FIB_FLUSH_BD, mp);
6905
6906   mp->bd_id = htonl (bd_id);
6907
6908   S (mp);
6909   W (ret);
6910   return ret;
6911 }
6912
6913 static int
6914 api_l2fib_flush_int (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_l2fib_flush_int_t *mp;
6918   u32 sw_if_index = ~0;
6919   int ret;
6920
6921   /* Parse args required to build the message */
6922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6923     {
6924       if (unformat (i, "sw_if_index %d", &sw_if_index));
6925       else
6926         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6927       else
6928         break;
6929     }
6930
6931   if (sw_if_index == ~0)
6932     {
6933       errmsg ("missing interface name or sw_if_index");
6934       return -99;
6935     }
6936
6937   M (L2FIB_FLUSH_INT, mp);
6938
6939   mp->sw_if_index = ntohl (sw_if_index);
6940
6941   S (mp);
6942   W (ret);
6943   return ret;
6944 }
6945
6946 static int
6947 api_l2fib_add_del (vat_main_t * vam)
6948 {
6949   unformat_input_t *i = vam->input;
6950   vl_api_l2fib_add_del_t *mp;
6951   f64 timeout;
6952   u8 mac[6] = { 0 };
6953   u8 mac_set = 0;
6954   u32 bd_id;
6955   u8 bd_id_set = 0;
6956   u32 sw_if_index = 0;
6957   u8 sw_if_index_set = 0;
6958   u8 is_add = 1;
6959   u8 static_mac = 0;
6960   u8 filter_mac = 0;
6961   u8 bvi_mac = 0;
6962   int count = 1;
6963   f64 before = 0;
6964   int j;
6965
6966   /* Parse args required to build the message */
6967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968     {
6969       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6970         mac_set = 1;
6971       else if (unformat (i, "bd_id %d", &bd_id))
6972         bd_id_set = 1;
6973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6974         sw_if_index_set = 1;
6975       else if (unformat (i, "sw_if"))
6976         {
6977           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978             {
6979               if (unformat
6980                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6981                 sw_if_index_set = 1;
6982             }
6983           else
6984             break;
6985         }
6986       else if (unformat (i, "static"))
6987         static_mac = 1;
6988       else if (unformat (i, "filter"))
6989         {
6990           filter_mac = 1;
6991           static_mac = 1;
6992         }
6993       else if (unformat (i, "bvi"))
6994         {
6995           bvi_mac = 1;
6996           static_mac = 1;
6997         }
6998       else if (unformat (i, "del"))
6999         is_add = 0;
7000       else if (unformat (i, "count %d", &count))
7001         ;
7002       else
7003         break;
7004     }
7005
7006   if (mac_set == 0)
7007     {
7008       errmsg ("missing mac address");
7009       return -99;
7010     }
7011
7012   if (bd_id_set == 0)
7013     {
7014       errmsg ("missing bridge domain");
7015       return -99;
7016     }
7017
7018   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7019     {
7020       errmsg ("missing interface name or sw_if_index");
7021       return -99;
7022     }
7023
7024   if (count > 1)
7025     {
7026       /* Turn on async mode */
7027       vam->async_mode = 1;
7028       vam->async_errors = 0;
7029       before = vat_time_now (vam);
7030     }
7031
7032   for (j = 0; j < count; j++)
7033     {
7034       M (L2FIB_ADD_DEL, mp);
7035
7036       clib_memcpy (mp->mac, mac, 6);
7037       mp->bd_id = ntohl (bd_id);
7038       mp->is_add = is_add;
7039       mp->sw_if_index = ntohl (sw_if_index);
7040
7041       if (is_add)
7042         {
7043           mp->static_mac = static_mac;
7044           mp->filter_mac = filter_mac;
7045           mp->bvi_mac = bvi_mac;
7046         }
7047       increment_mac_address (mac);
7048       /* send it... */
7049       S (mp);
7050     }
7051
7052   if (count > 1)
7053     {
7054       vl_api_control_ping_t *mp_ping;
7055       f64 after;
7056
7057       /* Shut off async mode */
7058       vam->async_mode = 0;
7059
7060       MPING (CONTROL_PING, mp_ping);
7061       S (mp_ping);
7062
7063       timeout = vat_time_now (vam) + 1.0;
7064       while (vat_time_now (vam) < timeout)
7065         if (vam->result_ready == 1)
7066           goto out;
7067       vam->retval = -99;
7068
7069     out:
7070       if (vam->retval == -99)
7071         errmsg ("timeout");
7072
7073       if (vam->async_errors > 0)
7074         {
7075           errmsg ("%d asynchronous errors", vam->async_errors);
7076           vam->retval = -98;
7077         }
7078       vam->async_errors = 0;
7079       after = vat_time_now (vam);
7080
7081       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7082              count, after - before, count / (after - before));
7083     }
7084   else
7085     {
7086       int ret;
7087
7088       /* Wait for a reply... */
7089       W (ret);
7090       return ret;
7091     }
7092   /* Return the good/bad news */
7093   return (vam->retval);
7094 }
7095
7096 static int
7097 api_bridge_domain_set_mac_age (vat_main_t * vam)
7098 {
7099   unformat_input_t *i = vam->input;
7100   vl_api_bridge_domain_set_mac_age_t *mp;
7101   u32 bd_id = ~0;
7102   u32 mac_age = 0;
7103   int ret;
7104
7105   /* Parse args required to build the message */
7106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7107     {
7108       if (unformat (i, "bd_id %d", &bd_id));
7109       else if (unformat (i, "mac-age %d", &mac_age));
7110       else
7111         break;
7112     }
7113
7114   if (bd_id == ~0)
7115     {
7116       errmsg ("missing bridge domain");
7117       return -99;
7118     }
7119
7120   if (mac_age > 255)
7121     {
7122       errmsg ("mac age must be less than 256 ");
7123       return -99;
7124     }
7125
7126   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7127
7128   mp->bd_id = htonl (bd_id);
7129   mp->mac_age = (u8) mac_age;
7130
7131   S (mp);
7132   W (ret);
7133   return ret;
7134 }
7135
7136 static int
7137 api_l2_flags (vat_main_t * vam)
7138 {
7139   unformat_input_t *i = vam->input;
7140   vl_api_l2_flags_t *mp;
7141   u32 sw_if_index;
7142   u32 flags = 0;
7143   u8 sw_if_index_set = 0;
7144   u8 is_set = 0;
7145   int ret;
7146
7147   /* Parse args required to build the message */
7148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149     {
7150       if (unformat (i, "sw_if_index %d", &sw_if_index))
7151         sw_if_index_set = 1;
7152       else if (unformat (i, "sw_if"))
7153         {
7154           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155             {
7156               if (unformat
7157                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158                 sw_if_index_set = 1;
7159             }
7160           else
7161             break;
7162         }
7163       else if (unformat (i, "learn"))
7164         flags |= L2_LEARN;
7165       else if (unformat (i, "forward"))
7166         flags |= L2_FWD;
7167       else if (unformat (i, "flood"))
7168         flags |= L2_FLOOD;
7169       else if (unformat (i, "uu-flood"))
7170         flags |= L2_UU_FLOOD;
7171       else if (unformat (i, "arp-term"))
7172         flags |= L2_ARP_TERM;
7173       else if (unformat (i, "off"))
7174         is_set = 0;
7175       else if (unformat (i, "disable"))
7176         is_set = 0;
7177       else
7178         break;
7179     }
7180
7181   if (sw_if_index_set == 0)
7182     {
7183       errmsg ("missing interface name or sw_if_index");
7184       return -99;
7185     }
7186
7187   M (L2_FLAGS, mp);
7188
7189   mp->sw_if_index = ntohl (sw_if_index);
7190   mp->feature_bitmap = ntohl (flags);
7191   mp->is_set = is_set;
7192
7193   S (mp);
7194   W (ret);
7195   return ret;
7196 }
7197
7198 static int
7199 api_bridge_flags (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_bridge_flags_t *mp;
7203   u32 bd_id;
7204   u8 bd_id_set = 0;
7205   u8 is_set = 1;
7206   bd_flags_t flags = 0;
7207   int ret;
7208
7209   /* Parse args required to build the message */
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "bd_id %d", &bd_id))
7213         bd_id_set = 1;
7214       else if (unformat (i, "learn"))
7215         flags |= BRIDGE_API_FLAG_LEARN;
7216       else if (unformat (i, "forward"))
7217         flags |= BRIDGE_API_FLAG_FWD;
7218       else if (unformat (i, "flood"))
7219         flags |= BRIDGE_API_FLAG_FLOOD;
7220       else if (unformat (i, "uu-flood"))
7221         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7222       else if (unformat (i, "arp-term"))
7223         flags |= BRIDGE_API_FLAG_ARP_TERM;
7224       else if (unformat (i, "off"))
7225         is_set = 0;
7226       else if (unformat (i, "disable"))
7227         is_set = 0;
7228       else
7229         break;
7230     }
7231
7232   if (bd_id_set == 0)
7233     {
7234       errmsg ("missing bridge domain");
7235       return -99;
7236     }
7237
7238   M (BRIDGE_FLAGS, mp);
7239
7240   mp->bd_id = ntohl (bd_id);
7241   mp->flags = ntohl (flags);
7242   mp->is_set = is_set;
7243
7244   S (mp);
7245   W (ret);
7246   return ret;
7247 }
7248
7249 static int
7250 api_bd_ip_mac_add_del (vat_main_t * vam)
7251 {
7252   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7253   vl_api_mac_address_t mac = { 0 };
7254   unformat_input_t *i = vam->input;
7255   vl_api_bd_ip_mac_add_del_t *mp;
7256   u32 bd_id;
7257   u8 is_add = 1;
7258   u8 bd_id_set = 0;
7259   u8 ip_set = 0;
7260   u8 mac_set = 0;
7261   int ret;
7262
7263
7264   /* Parse args required to build the message */
7265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7266     {
7267       if (unformat (i, "bd_id %d", &bd_id))
7268         {
7269           bd_id_set++;
7270         }
7271       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7272         {
7273           ip_set++;
7274         }
7275       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7276         {
7277           mac_set++;
7278         }
7279       else if (unformat (i, "del"))
7280         is_add = 0;
7281       else
7282         break;
7283     }
7284
7285   if (bd_id_set == 0)
7286     {
7287       errmsg ("missing bridge domain");
7288       return -99;
7289     }
7290   else if (ip_set == 0)
7291     {
7292       errmsg ("missing IP address");
7293       return -99;
7294     }
7295   else if (mac_set == 0)
7296     {
7297       errmsg ("missing MAC address");
7298       return -99;
7299     }
7300
7301   M (BD_IP_MAC_ADD_DEL, mp);
7302
7303   mp->entry.bd_id = ntohl (bd_id);
7304   mp->is_add = is_add;
7305
7306   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7307   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7308
7309   S (mp);
7310   W (ret);
7311   return ret;
7312 }
7313
7314 static int
7315 api_bd_ip_mac_flush (vat_main_t * vam)
7316 {
7317   unformat_input_t *i = vam->input;
7318   vl_api_bd_ip_mac_flush_t *mp;
7319   u32 bd_id;
7320   u8 bd_id_set = 0;
7321   int ret;
7322
7323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7324     {
7325       if (unformat (i, "bd_id %d", &bd_id))
7326         {
7327           bd_id_set++;
7328         }
7329       else
7330         break;
7331     }
7332
7333   if (bd_id_set == 0)
7334     {
7335       errmsg ("missing bridge domain");
7336       return -99;
7337     }
7338
7339   M (BD_IP_MAC_FLUSH, mp);
7340
7341   mp->bd_id = ntohl (bd_id);
7342
7343   S (mp);
7344   W (ret);
7345   return ret;
7346 }
7347
7348 static void vl_api_bd_ip_mac_details_t_handler
7349   (vl_api_bd_ip_mac_details_t * mp)
7350 {
7351   vat_main_t *vam = &vat_main;
7352
7353   print (vam->ofp,
7354          "\n%-5d %U %U",
7355          ntohl (mp->entry.bd_id),
7356          format_vl_api_mac_address, mp->entry.mac,
7357          format_vl_api_address, &mp->entry.ip);
7358 }
7359
7360 static void vl_api_bd_ip_mac_details_t_handler_json
7361   (vl_api_bd_ip_mac_details_t * mp)
7362 {
7363   vat_main_t *vam = &vat_main;
7364   vat_json_node_t *node = NULL;
7365
7366   if (VAT_JSON_ARRAY != vam->json_tree.type)
7367     {
7368       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7369       vat_json_init_array (&vam->json_tree);
7370     }
7371   node = vat_json_array_add (&vam->json_tree);
7372
7373   vat_json_init_object (node);
7374   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7375   vat_json_object_add_string_copy (node, "mac_address",
7376                                    format (0, "%U", format_vl_api_mac_address,
7377                                            &mp->entry.mac));
7378   u8 *ip = 0;
7379
7380   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7381   vat_json_object_add_string_copy (node, "ip_address", ip);
7382   vec_free (ip);
7383 }
7384
7385 static int
7386 api_bd_ip_mac_dump (vat_main_t * vam)
7387 {
7388   unformat_input_t *i = vam->input;
7389   vl_api_bd_ip_mac_dump_t *mp;
7390   vl_api_control_ping_t *mp_ping;
7391   int ret;
7392   u32 bd_id;
7393   u8 bd_id_set = 0;
7394
7395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7396     {
7397       if (unformat (i, "bd_id %d", &bd_id))
7398         {
7399           bd_id_set++;
7400         }
7401       else
7402         break;
7403     }
7404
7405   print (vam->ofp,
7406          "\n%-5s %-7s %-20s %-30s",
7407          "bd_id", "is_ipv6", "mac_address", "ip_address");
7408
7409   /* Dump Bridge Domain Ip to Mac entries */
7410   M (BD_IP_MAC_DUMP, mp);
7411
7412   if (bd_id_set)
7413     mp->bd_id = htonl (bd_id);
7414   else
7415     mp->bd_id = ~0;
7416
7417   S (mp);
7418
7419   /* Use a control ping for synchronization */
7420   MPING (CONTROL_PING, mp_ping);
7421   S (mp_ping);
7422
7423   W (ret);
7424   return ret;
7425 }
7426
7427 static int
7428 api_tap_create_v2 (vat_main_t * vam)
7429 {
7430   unformat_input_t *i = vam->input;
7431   vl_api_tap_create_v2_t *mp;
7432 #define TAP_FLAG_GSO (1 << 0)
7433   u8 mac_address[6];
7434   u8 random_mac = 1;
7435   u32 id = ~0;
7436   u8 *host_if_name = 0;
7437   u8 *host_ns = 0;
7438   u8 host_mac_addr[6];
7439   u8 host_mac_addr_set = 0;
7440   u8 *host_bridge = 0;
7441   ip4_address_t host_ip4_addr;
7442   ip4_address_t host_ip4_gw;
7443   u8 host_ip4_gw_set = 0;
7444   u32 host_ip4_prefix_len = 0;
7445   ip6_address_t host_ip6_addr;
7446   ip6_address_t host_ip6_gw;
7447   u8 host_ip6_gw_set = 0;
7448   u32 host_ip6_prefix_len = 0;
7449   u8 host_mtu_set = 0;
7450   u32 host_mtu_size = 0;
7451   u32 tap_flags = 0;
7452   int ret;
7453   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7454
7455   clib_memset (mac_address, 0, sizeof (mac_address));
7456
7457   /* Parse args required to build the message */
7458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7461         {
7462           random_mac = 0;
7463         }
7464       else if (unformat (i, "id %u", &id))
7465         ;
7466       else if (unformat (i, "host-if-name %s", &host_if_name))
7467         ;
7468       else if (unformat (i, "host-ns %s", &host_ns))
7469         ;
7470       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7471                          host_mac_addr))
7472         host_mac_addr_set = 1;
7473       else if (unformat (i, "host-bridge %s", &host_bridge))
7474         ;
7475       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7476                          &host_ip4_addr, &host_ip4_prefix_len))
7477         ;
7478       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7479                          &host_ip6_addr, &host_ip6_prefix_len))
7480         ;
7481       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7482                          &host_ip4_gw))
7483         host_ip4_gw_set = 1;
7484       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7485                          &host_ip6_gw))
7486         host_ip6_gw_set = 1;
7487       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7488         ;
7489       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7490         ;
7491       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7492         host_mtu_set = 1;
7493       else if (unformat (i, "no-gso"))
7494         tap_flags &= ~TAP_FLAG_GSO;
7495       else if (unformat (i, "gso"))
7496         tap_flags |= TAP_FLAG_GSO;
7497       else
7498         break;
7499     }
7500
7501   if (vec_len (host_if_name) > 63)
7502     {
7503       errmsg ("tap name too long. ");
7504       return -99;
7505     }
7506   if (vec_len (host_ns) > 63)
7507     {
7508       errmsg ("host name space too long. ");
7509       return -99;
7510     }
7511   if (vec_len (host_bridge) > 63)
7512     {
7513       errmsg ("host bridge name too long. ");
7514       return -99;
7515     }
7516   if (host_ip4_prefix_len > 32)
7517     {
7518       errmsg ("host ip4 prefix length not valid. ");
7519       return -99;
7520     }
7521   if (host_ip6_prefix_len > 128)
7522     {
7523       errmsg ("host ip6 prefix length not valid. ");
7524       return -99;
7525     }
7526   if (!is_pow2 (rx_ring_sz))
7527     {
7528       errmsg ("rx ring size must be power of 2. ");
7529       return -99;
7530     }
7531   if (rx_ring_sz > 32768)
7532     {
7533       errmsg ("rx ring size must be 32768 or lower. ");
7534       return -99;
7535     }
7536   if (!is_pow2 (tx_ring_sz))
7537     {
7538       errmsg ("tx ring size must be power of 2. ");
7539       return -99;
7540     }
7541   if (tx_ring_sz > 32768)
7542     {
7543       errmsg ("tx ring size must be 32768 or lower. ");
7544       return -99;
7545     }
7546   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7547     {
7548       errmsg ("host MTU size must be in between 64 and 65355. ");
7549       return -99;
7550     }
7551
7552   /* Construct the API message */
7553   M (TAP_CREATE_V2, mp);
7554
7555   mp->use_random_mac = random_mac;
7556
7557   mp->id = ntohl (id);
7558   mp->host_namespace_set = host_ns != 0;
7559   mp->host_bridge_set = host_bridge != 0;
7560   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7561   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7562   mp->rx_ring_sz = ntohs (rx_ring_sz);
7563   mp->tx_ring_sz = ntohs (tx_ring_sz);
7564   mp->host_mtu_set = host_mtu_set;
7565   mp->host_mtu_size = ntohl (host_mtu_size);
7566   mp->tap_flags = ntohl (tap_flags);
7567
7568   if (random_mac == 0)
7569     clib_memcpy (mp->mac_address, mac_address, 6);
7570   if (host_mac_addr_set)
7571     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7572   if (host_if_name)
7573     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7574   if (host_ns)
7575     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7576   if (host_bridge)
7577     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7578   if (host_ip4_prefix_len)
7579     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7580   if (host_ip6_prefix_len)
7581     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7582   if (host_ip4_gw_set)
7583     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7584   if (host_ip6_gw_set)
7585     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7586
7587   vec_free (host_ns);
7588   vec_free (host_if_name);
7589   vec_free (host_bridge);
7590
7591   /* send it... */
7592   S (mp);
7593
7594   /* Wait for a reply... */
7595   W (ret);
7596   return ret;
7597 }
7598
7599 static int
7600 api_tap_delete_v2 (vat_main_t * vam)
7601 {
7602   unformat_input_t *i = vam->input;
7603   vl_api_tap_delete_v2_t *mp;
7604   u32 sw_if_index = ~0;
7605   u8 sw_if_index_set = 0;
7606   int ret;
7607
7608   /* Parse args required to build the message */
7609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7610     {
7611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7612         sw_if_index_set = 1;
7613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7614         sw_if_index_set = 1;
7615       else
7616         break;
7617     }
7618
7619   if (sw_if_index_set == 0)
7620     {
7621       errmsg ("missing vpp interface name. ");
7622       return -99;
7623     }
7624
7625   /* Construct the API message */
7626   M (TAP_DELETE_V2, mp);
7627
7628   mp->sw_if_index = ntohl (sw_if_index);
7629
7630   /* send it... */
7631   S (mp);
7632
7633   /* Wait for a reply... */
7634   W (ret);
7635   return ret;
7636 }
7637
7638 uword
7639 unformat_pci_addr (unformat_input_t * input, va_list * args)
7640 {
7641   struct pci_addr_t
7642   {
7643     u16 domain;
7644     u8 bus;
7645     u8 slot:5;
7646     u8 function:3;
7647   } *addr;
7648   addr = va_arg (*args, struct pci_addr_t *);
7649   u32 x[4];
7650
7651   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7652     return 0;
7653
7654   addr->domain = x[0];
7655   addr->bus = x[1];
7656   addr->slot = x[2];
7657   addr->function = x[3];
7658
7659   return 1;
7660 }
7661
7662 static int
7663 api_virtio_pci_create (vat_main_t * vam)
7664 {
7665   unformat_input_t *i = vam->input;
7666   vl_api_virtio_pci_create_t *mp;
7667   u8 mac_address[6];
7668   u8 random_mac = 1;
7669   u8 gso_enabled = 0;
7670   u32 pci_addr = 0;
7671   u64 features = (u64) ~ (0ULL);
7672   int ret;
7673
7674   clib_memset (mac_address, 0, sizeof (mac_address));
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7680         {
7681           random_mac = 0;
7682         }
7683       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7684         ;
7685       else if (unformat (i, "features 0x%llx", &features))
7686         ;
7687       else if (unformat (i, "gso-enabled"))
7688         gso_enabled = 1;
7689       else
7690         break;
7691     }
7692
7693   if (pci_addr == 0)
7694     {
7695       errmsg ("pci address must be non zero. ");
7696       return -99;
7697     }
7698
7699   /* Construct the API message */
7700   M (VIRTIO_PCI_CREATE, mp);
7701
7702   mp->use_random_mac = random_mac;
7703
7704   mp->pci_addr = htonl (pci_addr);
7705   mp->features = clib_host_to_net_u64 (features);
7706   mp->gso_enabled = gso_enabled;
7707
7708   if (random_mac == 0)
7709     clib_memcpy (mp->mac_address, mac_address, 6);
7710
7711   /* send it... */
7712   S (mp);
7713
7714   /* Wait for a reply... */
7715   W (ret);
7716   return ret;
7717 }
7718
7719 static int
7720 api_virtio_pci_delete (vat_main_t * vam)
7721 {
7722   unformat_input_t *i = vam->input;
7723   vl_api_virtio_pci_delete_t *mp;
7724   u32 sw_if_index = ~0;
7725   u8 sw_if_index_set = 0;
7726   int ret;
7727
7728   /* Parse args required to build the message */
7729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7730     {
7731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7732         sw_if_index_set = 1;
7733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7734         sw_if_index_set = 1;
7735       else
7736         break;
7737     }
7738
7739   if (sw_if_index_set == 0)
7740     {
7741       errmsg ("missing vpp interface name. ");
7742       return -99;
7743     }
7744
7745   /* Construct the API message */
7746   M (VIRTIO_PCI_DELETE, mp);
7747
7748   mp->sw_if_index = htonl (sw_if_index);
7749
7750   /* send it... */
7751   S (mp);
7752
7753   /* Wait for a reply... */
7754   W (ret);
7755   return ret;
7756 }
7757
7758 static int
7759 api_bond_create (vat_main_t * vam)
7760 {
7761   unformat_input_t *i = vam->input;
7762   vl_api_bond_create_t *mp;
7763   u8 mac_address[6];
7764   u8 custom_mac = 0;
7765   int ret;
7766   u8 mode;
7767   u8 lb;
7768   u8 mode_is_set = 0;
7769   u32 id = ~0;
7770
7771   clib_memset (mac_address, 0, sizeof (mac_address));
7772   lb = BOND_LB_L2;
7773
7774   /* Parse args required to build the message */
7775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7776     {
7777       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7778         mode_is_set = 1;
7779       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7780                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7781         ;
7782       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7783                          mac_address))
7784         custom_mac = 1;
7785       else if (unformat (i, "id %u", &id))
7786         ;
7787       else
7788         break;
7789     }
7790
7791   if (mode_is_set == 0)
7792     {
7793       errmsg ("Missing bond mode. ");
7794       return -99;
7795     }
7796
7797   /* Construct the API message */
7798   M (BOND_CREATE, mp);
7799
7800   mp->use_custom_mac = custom_mac;
7801
7802   mp->mode = mode;
7803   mp->lb = lb;
7804   mp->id = htonl (id);
7805
7806   if (custom_mac)
7807     clib_memcpy (mp->mac_address, mac_address, 6);
7808
7809   /* send it... */
7810   S (mp);
7811
7812   /* Wait for a reply... */
7813   W (ret);
7814   return ret;
7815 }
7816
7817 static int
7818 api_bond_delete (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_bond_delete_t *mp;
7822   u32 sw_if_index = ~0;
7823   u8 sw_if_index_set = 0;
7824   int ret;
7825
7826   /* Parse args required to build the message */
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7830         sw_if_index_set = 1;
7831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7832         sw_if_index_set = 1;
7833       else
7834         break;
7835     }
7836
7837   if (sw_if_index_set == 0)
7838     {
7839       errmsg ("missing vpp interface name. ");
7840       return -99;
7841     }
7842
7843   /* Construct the API message */
7844   M (BOND_DELETE, mp);
7845
7846   mp->sw_if_index = ntohl (sw_if_index);
7847
7848   /* send it... */
7849   S (mp);
7850
7851   /* Wait for a reply... */
7852   W (ret);
7853   return ret;
7854 }
7855
7856 static int
7857 api_bond_enslave (vat_main_t * vam)
7858 {
7859   unformat_input_t *i = vam->input;
7860   vl_api_bond_enslave_t *mp;
7861   u32 bond_sw_if_index;
7862   int ret;
7863   u8 is_passive;
7864   u8 is_long_timeout;
7865   u32 bond_sw_if_index_is_set = 0;
7866   u32 sw_if_index;
7867   u8 sw_if_index_is_set = 0;
7868
7869   /* Parse args required to build the message */
7870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7871     {
7872       if (unformat (i, "sw_if_index %d", &sw_if_index))
7873         sw_if_index_is_set = 1;
7874       else if (unformat (i, "bond %u", &bond_sw_if_index))
7875         bond_sw_if_index_is_set = 1;
7876       else if (unformat (i, "passive %d", &is_passive))
7877         ;
7878       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7879         ;
7880       else
7881         break;
7882     }
7883
7884   if (bond_sw_if_index_is_set == 0)
7885     {
7886       errmsg ("Missing bond sw_if_index. ");
7887       return -99;
7888     }
7889   if (sw_if_index_is_set == 0)
7890     {
7891       errmsg ("Missing slave sw_if_index. ");
7892       return -99;
7893     }
7894
7895   /* Construct the API message */
7896   M (BOND_ENSLAVE, mp);
7897
7898   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7899   mp->sw_if_index = ntohl (sw_if_index);
7900   mp->is_long_timeout = is_long_timeout;
7901   mp->is_passive = is_passive;
7902
7903   /* send it... */
7904   S (mp);
7905
7906   /* Wait for a reply... */
7907   W (ret);
7908   return ret;
7909 }
7910
7911 static int
7912 api_bond_detach_slave (vat_main_t * vam)
7913 {
7914   unformat_input_t *i = vam->input;
7915   vl_api_bond_detach_slave_t *mp;
7916   u32 sw_if_index = ~0;
7917   u8 sw_if_index_set = 0;
7918   int ret;
7919
7920   /* Parse args required to build the message */
7921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7922     {
7923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7924         sw_if_index_set = 1;
7925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7926         sw_if_index_set = 1;
7927       else
7928         break;
7929     }
7930
7931   if (sw_if_index_set == 0)
7932     {
7933       errmsg ("missing vpp interface name. ");
7934       return -99;
7935     }
7936
7937   /* Construct the API message */
7938   M (BOND_DETACH_SLAVE, mp);
7939
7940   mp->sw_if_index = ntohl (sw_if_index);
7941
7942   /* send it... */
7943   S (mp);
7944
7945   /* Wait for a reply... */
7946   W (ret);
7947   return ret;
7948 }
7949
7950 static int
7951 api_ip_table_add_del (vat_main_t * vam)
7952 {
7953   unformat_input_t *i = vam->input;
7954   vl_api_ip_table_add_del_t *mp;
7955   u32 table_id = ~0;
7956   u8 is_ipv6 = 0;
7957   u8 is_add = 1;
7958   int ret = 0;
7959
7960   /* Parse args required to build the message */
7961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7962     {
7963       if (unformat (i, "ipv6"))
7964         is_ipv6 = 1;
7965       else if (unformat (i, "del"))
7966         is_add = 0;
7967       else if (unformat (i, "add"))
7968         is_add = 1;
7969       else if (unformat (i, "table %d", &table_id))
7970         ;
7971       else
7972         {
7973           clib_warning ("parse error '%U'", format_unformat_error, i);
7974           return -99;
7975         }
7976     }
7977
7978   if (~0 == table_id)
7979     {
7980       errmsg ("missing table-ID");
7981       return -99;
7982     }
7983
7984   /* Construct the API message */
7985   M (IP_TABLE_ADD_DEL, mp);
7986
7987   mp->table.table_id = ntohl (table_id);
7988   mp->table.is_ip6 = is_ipv6;
7989   mp->is_add = is_add;
7990
7991   /* send it... */
7992   S (mp);
7993
7994   /* Wait for a reply... */
7995   W (ret);
7996
7997   return ret;
7998 }
7999
8000 uword
8001 unformat_fib_path (unformat_input_t * input, va_list * args)
8002 {
8003   vat_main_t *vam = va_arg (*args, vat_main_t *);
8004   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8005   u32 weight, preference;
8006   mpls_label_t out_label;
8007
8008   clib_memset (path, 0, sizeof (*path));
8009   path->weight = 1;
8010   path->sw_if_index = ~0;
8011   path->rpf_id = ~0;
8012   path->n_labels = 0;
8013
8014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (input, "%U %U",
8017                     unformat_vl_api_ip4_address,
8018                     &path->nh.address.ip4,
8019                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8020         {
8021           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8022         }
8023       else if (unformat (input, "%U %U",
8024                          unformat_vl_api_ip6_address,
8025                          &path->nh.address.ip6,
8026                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8027         {
8028           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8029         }
8030       else if (unformat (input, "weight %u", &weight))
8031         {
8032           path->weight = weight;
8033         }
8034       else if (unformat (input, "preference %u", &preference))
8035         {
8036           path->preference = preference;
8037         }
8038       else if (unformat (input, "%U next-hop-table %d",
8039                          unformat_vl_api_ip4_address,
8040                          &path->nh.address.ip4, &path->table_id))
8041         {
8042           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8043         }
8044       else if (unformat (input, "%U next-hop-table %d",
8045                          unformat_vl_api_ip6_address,
8046                          &path->nh.address.ip6, &path->table_id))
8047         {
8048           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8049         }
8050       else if (unformat (input, "%U",
8051                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8052         {
8053           /*
8054            * the recursive next-hops are by default in the default table
8055            */
8056           path->table_id = 0;
8057           path->sw_if_index = ~0;
8058           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8059         }
8060       else if (unformat (input, "%U",
8061                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8062         {
8063           /*
8064            * the recursive next-hops are by default in the default table
8065            */
8066           path->table_id = 0;
8067           path->sw_if_index = ~0;
8068           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8069         }
8070       else if (unformat (input, "resolve-via-host"))
8071         {
8072           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8073         }
8074       else if (unformat (input, "resolve-via-attached"))
8075         {
8076           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8077         }
8078       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8079         {
8080           path->type = FIB_API_PATH_TYPE_LOCAL;
8081           path->sw_if_index = ~0;
8082           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8083         }
8084       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8085         {
8086           path->type = FIB_API_PATH_TYPE_LOCAL;
8087           path->sw_if_index = ~0;
8088           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8089         }
8090       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8091         ;
8092       else if (unformat (input, "via-label %d", &path->nh.via_label))
8093         {
8094           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8095           path->sw_if_index = ~0;
8096         }
8097       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8098         {
8099           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8100           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8101         }
8102       else if (unformat (input, "local"))
8103         {
8104           path->type = FIB_API_PATH_TYPE_LOCAL;
8105         }
8106       else if (unformat (input, "out-labels"))
8107         {
8108           while (unformat (input, "%d", &out_label))
8109             {
8110               path->label_stack[path->n_labels].label = out_label;
8111               path->label_stack[path->n_labels].is_uniform = 0;
8112               path->label_stack[path->n_labels].ttl = 64;
8113               path->n_labels++;
8114             }
8115         }
8116       else if (unformat (input, "via"))
8117         {
8118           /* new path, back up and return */
8119           unformat_put_input (input);
8120           unformat_put_input (input);
8121           unformat_put_input (input);
8122           unformat_put_input (input);
8123           break;
8124         }
8125       else
8126         {
8127           return (0);
8128         }
8129     }
8130
8131   path->proto = ntohl (path->proto);
8132   path->type = ntohl (path->type);
8133   path->flags = ntohl (path->flags);
8134   path->table_id = ntohl (path->table_id);
8135   path->sw_if_index = ntohl (path->sw_if_index);
8136
8137   return (1);
8138 }
8139
8140 static int
8141 api_ip_route_add_del (vat_main_t * vam)
8142 {
8143   unformat_input_t *i = vam->input;
8144   vl_api_ip_route_add_del_t *mp;
8145   u32 vrf_id = 0;
8146   u8 is_add = 1;
8147   u8 is_multipath = 0;
8148   u8 prefix_set = 0;
8149   u8 path_count = 0;
8150   vl_api_prefix_t pfx = { };
8151   vl_api_fib_path_t paths[8];
8152   int count = 1;
8153   int j;
8154   f64 before = 0;
8155   u32 random_add_del = 0;
8156   u32 *random_vector = 0;
8157   u32 random_seed = 0xdeaddabe;
8158
8159   /* Parse args required to build the message */
8160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8161     {
8162       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8163         prefix_set = 1;
8164       else if (unformat (i, "del"))
8165         is_add = 0;
8166       else if (unformat (i, "add"))
8167         is_add = 1;
8168       else if (unformat (i, "vrf %d", &vrf_id))
8169         ;
8170       else if (unformat (i, "count %d", &count))
8171         ;
8172       else if (unformat (i, "random"))
8173         random_add_del = 1;
8174       else if (unformat (i, "multipath"))
8175         is_multipath = 1;
8176       else if (unformat (i, "seed %d", &random_seed))
8177         ;
8178       else
8179         if (unformat
8180             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8181         {
8182           path_count++;
8183           if (8 == path_count)
8184             {
8185               errmsg ("max 8 paths");
8186               return -99;
8187             }
8188         }
8189       else
8190         {
8191           clib_warning ("parse error '%U'", format_unformat_error, i);
8192           return -99;
8193         }
8194     }
8195
8196   if (!path_count)
8197     {
8198       errmsg ("specify a path; via ...");
8199       return -99;
8200     }
8201   if (prefix_set == 0)
8202     {
8203       errmsg ("missing prefix");
8204       return -99;
8205     }
8206
8207   /* Generate a pile of unique, random routes */
8208   if (random_add_del)
8209     {
8210       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8211       u32 this_random_address;
8212       uword *random_hash;
8213
8214       random_hash = hash_create (count, sizeof (uword));
8215
8216       hash_set (random_hash, i->as_u32, 1);
8217       for (j = 0; j <= count; j++)
8218         {
8219           do
8220             {
8221               this_random_address = random_u32 (&random_seed);
8222               this_random_address =
8223                 clib_host_to_net_u32 (this_random_address);
8224             }
8225           while (hash_get (random_hash, this_random_address));
8226           vec_add1 (random_vector, this_random_address);
8227           hash_set (random_hash, this_random_address, 1);
8228         }
8229       hash_free (random_hash);
8230       set_ip4_address (&pfx.address, random_vector[0]);
8231     }
8232
8233   if (count > 1)
8234     {
8235       /* Turn on async mode */
8236       vam->async_mode = 1;
8237       vam->async_errors = 0;
8238       before = vat_time_now (vam);
8239     }
8240
8241   for (j = 0; j < count; j++)
8242     {
8243       /* Construct the API message */
8244       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8245
8246       mp->is_add = is_add;
8247       mp->is_multipath = is_multipath;
8248
8249       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8250       mp->route.table_id = ntohl (vrf_id);
8251       mp->route.n_paths = path_count;
8252
8253       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8254
8255       if (random_add_del)
8256         set_ip4_address (&pfx.address, random_vector[j + 1]);
8257       else
8258         increment_address (&pfx.address);
8259       /* send it... */
8260       S (mp);
8261       /* If we receive SIGTERM, stop now... */
8262       if (vam->do_exit)
8263         break;
8264     }
8265
8266   /* When testing multiple add/del ops, use a control-ping to sync */
8267   if (count > 1)
8268     {
8269       vl_api_control_ping_t *mp_ping;
8270       f64 after;
8271       f64 timeout;
8272
8273       /* Shut off async mode */
8274       vam->async_mode = 0;
8275
8276       MPING (CONTROL_PING, mp_ping);
8277       S (mp_ping);
8278
8279       timeout = vat_time_now (vam) + 1.0;
8280       while (vat_time_now (vam) < timeout)
8281         if (vam->result_ready == 1)
8282           goto out;
8283       vam->retval = -99;
8284
8285     out:
8286       if (vam->retval == -99)
8287         errmsg ("timeout");
8288
8289       if (vam->async_errors > 0)
8290         {
8291           errmsg ("%d asynchronous errors", vam->async_errors);
8292           vam->retval = -98;
8293         }
8294       vam->async_errors = 0;
8295       after = vat_time_now (vam);
8296
8297       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8298       if (j > 0)
8299         count = j;
8300
8301       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8302              count, after - before, count / (after - before));
8303     }
8304   else
8305     {
8306       int ret;
8307
8308       /* Wait for a reply... */
8309       W (ret);
8310       return ret;
8311     }
8312
8313   /* Return the good/bad news */
8314   return (vam->retval);
8315 }
8316
8317 static int
8318 api_ip_mroute_add_del (vat_main_t * vam)
8319 {
8320   unformat_input_t *i = vam->input;
8321   u8 path_set = 0, prefix_set = 0, is_add = 1;
8322   vl_api_ip_mroute_add_del_t *mp;
8323   mfib_entry_flags_t eflags = 0;
8324   vl_api_mfib_path_t path;
8325   vl_api_mprefix_t pfx = { };
8326   u32 vrf_id = 0;
8327   int ret;
8328
8329   /* Parse args required to build the message */
8330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8331     {
8332       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8333         {
8334           prefix_set = 1;
8335           pfx.grp_address_length = htons (pfx.grp_address_length);
8336         }
8337       else if (unformat (i, "del"))
8338         is_add = 0;
8339       else if (unformat (i, "add"))
8340         is_add = 1;
8341       else if (unformat (i, "vrf %d", &vrf_id))
8342         ;
8343       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8344         path.itf_flags = htonl (path.itf_flags);
8345       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8346         ;
8347       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8348         path_set = 1;
8349       else
8350         {
8351           clib_warning ("parse error '%U'", format_unformat_error, i);
8352           return -99;
8353         }
8354     }
8355
8356   if (prefix_set == 0)
8357     {
8358       errmsg ("missing addresses\n");
8359       return -99;
8360     }
8361   if (path_set == 0)
8362     {
8363       errmsg ("missing path\n");
8364       return -99;
8365     }
8366
8367   /* Construct the API message */
8368   M (IP_MROUTE_ADD_DEL, mp);
8369
8370   mp->is_add = is_add;
8371   mp->is_multipath = 1;
8372
8373   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8374   mp->route.table_id = htonl (vrf_id);
8375   mp->route.n_paths = 1;
8376   mp->route.entry_flags = htonl (eflags);
8377
8378   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8379
8380   /* send it... */
8381   S (mp);
8382   /* Wait for a reply... */
8383   W (ret);
8384   return ret;
8385 }
8386
8387 static int
8388 api_mpls_table_add_del (vat_main_t * vam)
8389 {
8390   unformat_input_t *i = vam->input;
8391   vl_api_mpls_table_add_del_t *mp;
8392   u32 table_id = ~0;
8393   u8 is_add = 1;
8394   int ret = 0;
8395
8396   /* Parse args required to build the message */
8397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8398     {
8399       if (unformat (i, "table %d", &table_id))
8400         ;
8401       else if (unformat (i, "del"))
8402         is_add = 0;
8403       else if (unformat (i, "add"))
8404         is_add = 1;
8405       else
8406         {
8407           clib_warning ("parse error '%U'", format_unformat_error, i);
8408           return -99;
8409         }
8410     }
8411
8412   if (~0 == table_id)
8413     {
8414       errmsg ("missing table-ID");
8415       return -99;
8416     }
8417
8418   /* Construct the API message */
8419   M (MPLS_TABLE_ADD_DEL, mp);
8420
8421   mp->mt_table.mt_table_id = ntohl (table_id);
8422   mp->mt_is_add = is_add;
8423
8424   /* send it... */
8425   S (mp);
8426
8427   /* Wait for a reply... */
8428   W (ret);
8429
8430   return ret;
8431 }
8432
8433 static int
8434 api_mpls_route_add_del (vat_main_t * vam)
8435 {
8436   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8437   mpls_label_t local_label = MPLS_LABEL_INVALID;
8438   unformat_input_t *i = vam->input;
8439   vl_api_mpls_route_add_del_t *mp;
8440   vl_api_fib_path_t paths[8];
8441   int count = 1, j;
8442   f64 before = 0;
8443
8444   /* Parse args required to build the message */
8445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8446     {
8447       if (unformat (i, "%d", &local_label))
8448         ;
8449       else if (unformat (i, "eos"))
8450         is_eos = 1;
8451       else if (unformat (i, "non-eos"))
8452         is_eos = 0;
8453       else if (unformat (i, "del"))
8454         is_add = 0;
8455       else if (unformat (i, "add"))
8456         is_add = 1;
8457       else if (unformat (i, "multipath"))
8458         is_multipath = 1;
8459       else if (unformat (i, "count %d", &count))
8460         ;
8461       else
8462         if (unformat
8463             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8464         {
8465           path_count++;
8466           if (8 == path_count)
8467             {
8468               errmsg ("max 8 paths");
8469               return -99;
8470             }
8471         }
8472       else
8473         {
8474           clib_warning ("parse error '%U'", format_unformat_error, i);
8475           return -99;
8476         }
8477     }
8478
8479   if (!path_count)
8480     {
8481       errmsg ("specify a path; via ...");
8482       return -99;
8483     }
8484
8485   if (MPLS_LABEL_INVALID == local_label)
8486     {
8487       errmsg ("missing label");
8488       return -99;
8489     }
8490
8491   if (count > 1)
8492     {
8493       /* Turn on async mode */
8494       vam->async_mode = 1;
8495       vam->async_errors = 0;
8496       before = vat_time_now (vam);
8497     }
8498
8499   for (j = 0; j < count; j++)
8500     {
8501       /* Construct the API message */
8502       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8503
8504       mp->mr_is_add = is_add;
8505       mp->mr_is_multipath = is_multipath;
8506
8507       mp->mr_route.mr_label = local_label;
8508       mp->mr_route.mr_eos = is_eos;
8509       mp->mr_route.mr_table_id = 0;
8510       mp->mr_route.mr_n_paths = path_count;
8511
8512       clib_memcpy (&mp->mr_route.mr_paths, paths,
8513                    sizeof (paths[0]) * path_count);
8514
8515       local_label++;
8516
8517       /* send it... */
8518       S (mp);
8519       /* If we receive SIGTERM, stop now... */
8520       if (vam->do_exit)
8521         break;
8522     }
8523
8524   /* When testing multiple add/del ops, use a control-ping to sync */
8525   if (count > 1)
8526     {
8527       vl_api_control_ping_t *mp_ping;
8528       f64 after;
8529       f64 timeout;
8530
8531       /* Shut off async mode */
8532       vam->async_mode = 0;
8533
8534       MPING (CONTROL_PING, mp_ping);
8535       S (mp_ping);
8536
8537       timeout = vat_time_now (vam) + 1.0;
8538       while (vat_time_now (vam) < timeout)
8539         if (vam->result_ready == 1)
8540           goto out;
8541       vam->retval = -99;
8542
8543     out:
8544       if (vam->retval == -99)
8545         errmsg ("timeout");
8546
8547       if (vam->async_errors > 0)
8548         {
8549           errmsg ("%d asynchronous errors", vam->async_errors);
8550           vam->retval = -98;
8551         }
8552       vam->async_errors = 0;
8553       after = vat_time_now (vam);
8554
8555       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8556       if (j > 0)
8557         count = j;
8558
8559       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8560              count, after - before, count / (after - before));
8561     }
8562   else
8563     {
8564       int ret;
8565
8566       /* Wait for a reply... */
8567       W (ret);
8568       return ret;
8569     }
8570
8571   /* Return the good/bad news */
8572   return (vam->retval);
8573   return (0);
8574 }
8575
8576 static int
8577 api_mpls_ip_bind_unbind (vat_main_t * vam)
8578 {
8579   unformat_input_t *i = vam->input;
8580   vl_api_mpls_ip_bind_unbind_t *mp;
8581   u32 ip_table_id = 0;
8582   u8 is_bind = 1;
8583   vl_api_prefix_t pfx;
8584   u8 prefix_set = 0;
8585   mpls_label_t local_label = MPLS_LABEL_INVALID;
8586   int ret;
8587
8588   /* Parse args required to build the message */
8589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8590     {
8591       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8592         prefix_set = 1;
8593       else if (unformat (i, "%d", &local_label))
8594         ;
8595       else if (unformat (i, "table-id %d", &ip_table_id))
8596         ;
8597       else if (unformat (i, "unbind"))
8598         is_bind = 0;
8599       else if (unformat (i, "bind"))
8600         is_bind = 1;
8601       else
8602         {
8603           clib_warning ("parse error '%U'", format_unformat_error, i);
8604           return -99;
8605         }
8606     }
8607
8608   if (!prefix_set)
8609     {
8610       errmsg ("IP prefix not set");
8611       return -99;
8612     }
8613
8614   if (MPLS_LABEL_INVALID == local_label)
8615     {
8616       errmsg ("missing label");
8617       return -99;
8618     }
8619
8620   /* Construct the API message */
8621   M (MPLS_IP_BIND_UNBIND, mp);
8622
8623   mp->mb_is_bind = is_bind;
8624   mp->mb_ip_table_id = ntohl (ip_table_id);
8625   mp->mb_mpls_table_id = 0;
8626   mp->mb_label = ntohl (local_label);
8627   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8628
8629   /* send it... */
8630   S (mp);
8631
8632   /* Wait for a reply... */
8633   W (ret);
8634   return ret;
8635   return (0);
8636 }
8637
8638 static int
8639 api_sr_mpls_policy_add (vat_main_t * vam)
8640 {
8641   unformat_input_t *i = vam->input;
8642   vl_api_sr_mpls_policy_add_t *mp;
8643   u32 bsid = 0;
8644   u32 weight = 1;
8645   u8 type = 0;
8646   u8 n_segments = 0;
8647   u32 sid;
8648   u32 *segments = NULL;
8649   int ret;
8650
8651   /* Parse args required to build the message */
8652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8653     {
8654       if (unformat (i, "bsid %d", &bsid))
8655         ;
8656       else if (unformat (i, "weight %d", &weight))
8657         ;
8658       else if (unformat (i, "spray"))
8659         type = 1;
8660       else if (unformat (i, "next %d", &sid))
8661         {
8662           n_segments += 1;
8663           vec_add1 (segments, htonl (sid));
8664         }
8665       else
8666         {
8667           clib_warning ("parse error '%U'", format_unformat_error, i);
8668           return -99;
8669         }
8670     }
8671
8672   if (bsid == 0)
8673     {
8674       errmsg ("bsid not set");
8675       return -99;
8676     }
8677
8678   if (n_segments == 0)
8679     {
8680       errmsg ("no sid in segment stack");
8681       return -99;
8682     }
8683
8684   /* Construct the API message */
8685   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8686
8687   mp->bsid = htonl (bsid);
8688   mp->weight = htonl (weight);
8689   mp->type = type;
8690   mp->n_segments = n_segments;
8691   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8692   vec_free (segments);
8693
8694   /* send it... */
8695   S (mp);
8696
8697   /* Wait for a reply... */
8698   W (ret);
8699   return ret;
8700 }
8701
8702 static int
8703 api_sr_mpls_policy_del (vat_main_t * vam)
8704 {
8705   unformat_input_t *i = vam->input;
8706   vl_api_sr_mpls_policy_del_t *mp;
8707   u32 bsid = 0;
8708   int ret;
8709
8710   /* Parse args required to build the message */
8711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8712     {
8713       if (unformat (i, "bsid %d", &bsid))
8714         ;
8715       else
8716         {
8717           clib_warning ("parse error '%U'", format_unformat_error, i);
8718           return -99;
8719         }
8720     }
8721
8722   if (bsid == 0)
8723     {
8724       errmsg ("bsid not set");
8725       return -99;
8726     }
8727
8728   /* Construct the API message */
8729   M (SR_MPLS_POLICY_DEL, mp);
8730
8731   mp->bsid = htonl (bsid);
8732
8733   /* send it... */
8734   S (mp);
8735
8736   /* Wait for a reply... */
8737   W (ret);
8738   return ret;
8739 }
8740
8741 static int
8742 api_bier_table_add_del (vat_main_t * vam)
8743 {
8744   unformat_input_t *i = vam->input;
8745   vl_api_bier_table_add_del_t *mp;
8746   u8 is_add = 1;
8747   u32 set = 0, sub_domain = 0, hdr_len = 3;
8748   mpls_label_t local_label = MPLS_LABEL_INVALID;
8749   int ret;
8750
8751   /* Parse args required to build the message */
8752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8753     {
8754       if (unformat (i, "sub-domain %d", &sub_domain))
8755         ;
8756       else if (unformat (i, "set %d", &set))
8757         ;
8758       else if (unformat (i, "label %d", &local_label))
8759         ;
8760       else if (unformat (i, "hdr-len %d", &hdr_len))
8761         ;
8762       else if (unformat (i, "add"))
8763         is_add = 1;
8764       else if (unformat (i, "del"))
8765         is_add = 0;
8766       else
8767         {
8768           clib_warning ("parse error '%U'", format_unformat_error, i);
8769           return -99;
8770         }
8771     }
8772
8773   if (MPLS_LABEL_INVALID == local_label)
8774     {
8775       errmsg ("missing label\n");
8776       return -99;
8777     }
8778
8779   /* Construct the API message */
8780   M (BIER_TABLE_ADD_DEL, mp);
8781
8782   mp->bt_is_add = is_add;
8783   mp->bt_label = ntohl (local_label);
8784   mp->bt_tbl_id.bt_set = set;
8785   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8786   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8787
8788   /* send it... */
8789   S (mp);
8790
8791   /* Wait for a reply... */
8792   W (ret);
8793
8794   return (ret);
8795 }
8796
8797 static int
8798 api_bier_route_add_del (vat_main_t * vam)
8799 {
8800   unformat_input_t *i = vam->input;
8801   vl_api_bier_route_add_del_t *mp;
8802   u8 is_add = 1;
8803   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8804   ip4_address_t v4_next_hop_address;
8805   ip6_address_t v6_next_hop_address;
8806   u8 next_hop_set = 0;
8807   u8 next_hop_proto_is_ip4 = 1;
8808   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8809   int ret;
8810
8811   /* Parse args required to build the message */
8812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813     {
8814       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8815         {
8816           next_hop_proto_is_ip4 = 1;
8817           next_hop_set = 1;
8818         }
8819       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8820         {
8821           next_hop_proto_is_ip4 = 0;
8822           next_hop_set = 1;
8823         }
8824       if (unformat (i, "sub-domain %d", &sub_domain))
8825         ;
8826       else if (unformat (i, "set %d", &set))
8827         ;
8828       else if (unformat (i, "hdr-len %d", &hdr_len))
8829         ;
8830       else if (unformat (i, "bp %d", &bp))
8831         ;
8832       else if (unformat (i, "add"))
8833         is_add = 1;
8834       else if (unformat (i, "del"))
8835         is_add = 0;
8836       else if (unformat (i, "out-label %d", &next_hop_out_label))
8837         ;
8838       else
8839         {
8840           clib_warning ("parse error '%U'", format_unformat_error, i);
8841           return -99;
8842         }
8843     }
8844
8845   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8846     {
8847       errmsg ("next hop / label set\n");
8848       return -99;
8849     }
8850   if (0 == bp)
8851     {
8852       errmsg ("bit=position not set\n");
8853       return -99;
8854     }
8855
8856   /* Construct the API message */
8857   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8858
8859   mp->br_is_add = is_add;
8860   mp->br_route.br_tbl_id.bt_set = set;
8861   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8862   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8863   mp->br_route.br_bp = ntohs (bp);
8864   mp->br_route.br_n_paths = 1;
8865   mp->br_route.br_paths[0].n_labels = 1;
8866   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8867   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8868                                     FIB_API_PATH_NH_PROTO_IP4 :
8869                                     FIB_API_PATH_NH_PROTO_IP6);
8870
8871   if (next_hop_proto_is_ip4)
8872     {
8873       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8874                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8875     }
8876   else
8877     {
8878       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8879                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8880     }
8881
8882   /* send it... */
8883   S (mp);
8884
8885   /* Wait for a reply... */
8886   W (ret);
8887
8888   return (ret);
8889 }
8890
8891 static int
8892 api_proxy_arp_add_del (vat_main_t * vam)
8893 {
8894   unformat_input_t *i = vam->input;
8895   vl_api_proxy_arp_add_del_t *mp;
8896   u32 vrf_id = 0;
8897   u8 is_add = 1;
8898   vl_api_ip4_address_t lo, hi;
8899   u8 range_set = 0;
8900   int ret;
8901
8902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8903     {
8904       if (unformat (i, "vrf %d", &vrf_id))
8905         ;
8906       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8907                          unformat_vl_api_ip4_address, &hi))
8908         range_set = 1;
8909       else if (unformat (i, "del"))
8910         is_add = 0;
8911       else
8912         {
8913           clib_warning ("parse error '%U'", format_unformat_error, i);
8914           return -99;
8915         }
8916     }
8917
8918   if (range_set == 0)
8919     {
8920       errmsg ("address range not set");
8921       return -99;
8922     }
8923
8924   M (PROXY_ARP_ADD_DEL, mp);
8925
8926   mp->proxy.table_id = ntohl (vrf_id);
8927   mp->is_add = is_add;
8928   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8929   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8930
8931   S (mp);
8932   W (ret);
8933   return ret;
8934 }
8935
8936 static int
8937 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8938 {
8939   unformat_input_t *i = vam->input;
8940   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8941   u32 sw_if_index;
8942   u8 enable = 1;
8943   u8 sw_if_index_set = 0;
8944   int ret;
8945
8946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8947     {
8948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8949         sw_if_index_set = 1;
8950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8951         sw_if_index_set = 1;
8952       else if (unformat (i, "enable"))
8953         enable = 1;
8954       else if (unformat (i, "disable"))
8955         enable = 0;
8956       else
8957         {
8958           clib_warning ("parse error '%U'", format_unformat_error, i);
8959           return -99;
8960         }
8961     }
8962
8963   if (sw_if_index_set == 0)
8964     {
8965       errmsg ("missing interface name or sw_if_index");
8966       return -99;
8967     }
8968
8969   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8970
8971   mp->sw_if_index = ntohl (sw_if_index);
8972   mp->enable_disable = enable;
8973
8974   S (mp);
8975   W (ret);
8976   return ret;
8977 }
8978
8979 static int
8980 api_mpls_tunnel_add_del (vat_main_t * vam)
8981 {
8982   unformat_input_t *i = vam->input;
8983   vl_api_mpls_tunnel_add_del_t *mp;
8984
8985   vl_api_fib_path_t paths[8];
8986   u32 sw_if_index = ~0;
8987   u8 path_count = 0;
8988   u8 l2_only = 0;
8989   u8 is_add = 1;
8990   int ret;
8991
8992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (i, "add"))
8995         is_add = 1;
8996       else
8997         if (unformat
8998             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8999         is_add = 0;
9000       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9001         is_add = 0;
9002       else if (unformat (i, "l2-only"))
9003         l2_only = 1;
9004       else
9005         if (unformat
9006             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9007         {
9008           path_count++;
9009           if (8 == path_count)
9010             {
9011               errmsg ("max 8 paths");
9012               return -99;
9013             }
9014         }
9015       else
9016         {
9017           clib_warning ("parse error '%U'", format_unformat_error, i);
9018           return -99;
9019         }
9020     }
9021
9022   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9023
9024   mp->mt_is_add = is_add;
9025   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9026   mp->mt_tunnel.mt_l2_only = l2_only;
9027   mp->mt_tunnel.mt_is_multicast = 0;
9028   mp->mt_tunnel.mt_n_paths = path_count;
9029
9030   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9031                sizeof (paths[0]) * path_count);
9032
9033   S (mp);
9034   W (ret);
9035   return ret;
9036 }
9037
9038 static int
9039 api_sw_interface_set_unnumbered (vat_main_t * vam)
9040 {
9041   unformat_input_t *i = vam->input;
9042   vl_api_sw_interface_set_unnumbered_t *mp;
9043   u32 sw_if_index;
9044   u32 unnum_sw_index = ~0;
9045   u8 is_add = 1;
9046   u8 sw_if_index_set = 0;
9047   int ret;
9048
9049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9050     {
9051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9052         sw_if_index_set = 1;
9053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9054         sw_if_index_set = 1;
9055       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9056         ;
9057       else if (unformat (i, "del"))
9058         is_add = 0;
9059       else
9060         {
9061           clib_warning ("parse error '%U'", format_unformat_error, i);
9062           return -99;
9063         }
9064     }
9065
9066   if (sw_if_index_set == 0)
9067     {
9068       errmsg ("missing interface name or sw_if_index");
9069       return -99;
9070     }
9071
9072   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9073
9074   mp->sw_if_index = ntohl (sw_if_index);
9075   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9076   mp->is_add = is_add;
9077
9078   S (mp);
9079   W (ret);
9080   return ret;
9081 }
9082
9083 static int
9084 api_ip_neighbor_add_del (vat_main_t * vam)
9085 {
9086   vl_api_mac_address_t mac_address;
9087   unformat_input_t *i = vam->input;
9088   vl_api_ip_neighbor_add_del_t *mp;
9089   vl_api_address_t ip_address;
9090   u32 sw_if_index;
9091   u8 sw_if_index_set = 0;
9092   u8 is_add = 1;
9093   u8 mac_set = 0;
9094   u8 address_set = 0;
9095   int ret;
9096   ip_neighbor_flags_t flags;
9097
9098   flags = IP_NEIGHBOR_FLAG_NONE;
9099   clib_memset (&ip_address, 0, sizeof (ip_address));
9100   clib_memset (&mac_address, 0, sizeof (mac_address));
9101
9102   /* Parse args required to build the message */
9103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9104     {
9105       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9106         {
9107           mac_set = 1;
9108         }
9109       else if (unformat (i, "del"))
9110         is_add = 0;
9111       else
9112         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9113         sw_if_index_set = 1;
9114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9115         sw_if_index_set = 1;
9116       else if (unformat (i, "static"))
9117         flags |= IP_NEIGHBOR_FLAG_STATIC;
9118       else if (unformat (i, "no-fib-entry"))
9119         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9120       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9121         address_set = 1;
9122       else
9123         {
9124           clib_warning ("parse error '%U'", format_unformat_error, i);
9125           return -99;
9126         }
9127     }
9128
9129   if (sw_if_index_set == 0)
9130     {
9131       errmsg ("missing interface name or sw_if_index");
9132       return -99;
9133     }
9134   if (!address_set)
9135     {
9136       errmsg ("no address set");
9137       return -99;
9138     }
9139
9140   /* Construct the API message */
9141   M (IP_NEIGHBOR_ADD_DEL, mp);
9142
9143   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9144   mp->is_add = is_add;
9145   mp->neighbor.flags = htonl (flags);
9146   if (mac_set)
9147     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9148                  sizeof (mac_address));
9149   if (address_set)
9150     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9151
9152   /* send it... */
9153   S (mp);
9154
9155   /* Wait for a reply, return good/bad news  */
9156   W (ret);
9157   return ret;
9158 }
9159
9160 static int
9161 api_create_vlan_subif (vat_main_t * vam)
9162 {
9163   unformat_input_t *i = vam->input;
9164   vl_api_create_vlan_subif_t *mp;
9165   u32 sw_if_index;
9166   u8 sw_if_index_set = 0;
9167   u32 vlan_id;
9168   u8 vlan_id_set = 0;
9169   int ret;
9170
9171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9172     {
9173       if (unformat (i, "sw_if_index %d", &sw_if_index))
9174         sw_if_index_set = 1;
9175       else
9176         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9177         sw_if_index_set = 1;
9178       else if (unformat (i, "vlan %d", &vlan_id))
9179         vlan_id_set = 1;
9180       else
9181         {
9182           clib_warning ("parse error '%U'", format_unformat_error, i);
9183           return -99;
9184         }
9185     }
9186
9187   if (sw_if_index_set == 0)
9188     {
9189       errmsg ("missing interface name or sw_if_index");
9190       return -99;
9191     }
9192
9193   if (vlan_id_set == 0)
9194     {
9195       errmsg ("missing vlan_id");
9196       return -99;
9197     }
9198   M (CREATE_VLAN_SUBIF, mp);
9199
9200   mp->sw_if_index = ntohl (sw_if_index);
9201   mp->vlan_id = ntohl (vlan_id);
9202
9203   S (mp);
9204   W (ret);
9205   return ret;
9206 }
9207
9208 #define foreach_create_subif_bit                \
9209 _(no_tags)                                      \
9210 _(one_tag)                                      \
9211 _(two_tags)                                     \
9212 _(dot1ad)                                       \
9213 _(exact_match)                                  \
9214 _(default_sub)                                  \
9215 _(outer_vlan_id_any)                            \
9216 _(inner_vlan_id_any)
9217
9218 static int
9219 api_create_subif (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_create_subif_t *mp;
9223   u32 sw_if_index;
9224   u8 sw_if_index_set = 0;
9225   u32 sub_id;
9226   u8 sub_id_set = 0;
9227   u32 no_tags = 0;
9228   u32 one_tag = 0;
9229   u32 two_tags = 0;
9230   u32 dot1ad = 0;
9231   u32 exact_match = 0;
9232   u32 default_sub = 0;
9233   u32 outer_vlan_id_any = 0;
9234   u32 inner_vlan_id_any = 0;
9235   u32 tmp;
9236   u16 outer_vlan_id = 0;
9237   u16 inner_vlan_id = 0;
9238   int ret;
9239
9240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9241     {
9242       if (unformat (i, "sw_if_index %d", &sw_if_index))
9243         sw_if_index_set = 1;
9244       else
9245         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9246         sw_if_index_set = 1;
9247       else if (unformat (i, "sub_id %d", &sub_id))
9248         sub_id_set = 1;
9249       else if (unformat (i, "outer_vlan_id %d", &tmp))
9250         outer_vlan_id = tmp;
9251       else if (unformat (i, "inner_vlan_id %d", &tmp))
9252         inner_vlan_id = tmp;
9253
9254 #define _(a) else if (unformat (i, #a)) a = 1 ;
9255       foreach_create_subif_bit
9256 #undef _
9257         else
9258         {
9259           clib_warning ("parse error '%U'", format_unformat_error, i);
9260           return -99;
9261         }
9262     }
9263
9264   if (sw_if_index_set == 0)
9265     {
9266       errmsg ("missing interface name or sw_if_index");
9267       return -99;
9268     }
9269
9270   if (sub_id_set == 0)
9271     {
9272       errmsg ("missing sub_id");
9273       return -99;
9274     }
9275   M (CREATE_SUBIF, mp);
9276
9277   mp->sw_if_index = ntohl (sw_if_index);
9278   mp->sub_id = ntohl (sub_id);
9279
9280 #define _(a) mp->a = a;
9281   foreach_create_subif_bit;
9282 #undef _
9283
9284   mp->outer_vlan_id = ntohs (outer_vlan_id);
9285   mp->inner_vlan_id = ntohs (inner_vlan_id);
9286
9287   S (mp);
9288   W (ret);
9289   return ret;
9290 }
9291
9292 static int
9293 api_reset_fib (vat_main_t * vam)
9294 {
9295   unformat_input_t *i = vam->input;
9296   vl_api_reset_fib_t *mp;
9297   u32 vrf_id = 0;
9298   u8 is_ipv6 = 0;
9299   u8 vrf_id_set = 0;
9300
9301   int ret;
9302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9303     {
9304       if (unformat (i, "vrf %d", &vrf_id))
9305         vrf_id_set = 1;
9306       else if (unformat (i, "ipv6"))
9307         is_ipv6 = 1;
9308       else
9309         {
9310           clib_warning ("parse error '%U'", format_unformat_error, i);
9311           return -99;
9312         }
9313     }
9314
9315   if (vrf_id_set == 0)
9316     {
9317       errmsg ("missing vrf id");
9318       return -99;
9319     }
9320
9321   M (RESET_FIB, mp);
9322
9323   mp->vrf_id = ntohl (vrf_id);
9324   mp->is_ipv6 = is_ipv6;
9325
9326   S (mp);
9327   W (ret);
9328   return ret;
9329 }
9330
9331 static int
9332 api_dhcp_proxy_config (vat_main_t * vam)
9333 {
9334   unformat_input_t *i = vam->input;
9335   vl_api_dhcp_proxy_config_t *mp;
9336   u32 rx_vrf_id = 0;
9337   u32 server_vrf_id = 0;
9338   u8 is_add = 1;
9339   u8 v4_address_set = 0;
9340   u8 v6_address_set = 0;
9341   ip4_address_t v4address;
9342   ip6_address_t v6address;
9343   u8 v4_src_address_set = 0;
9344   u8 v6_src_address_set = 0;
9345   ip4_address_t v4srcaddress;
9346   ip6_address_t v6srcaddress;
9347   int ret;
9348
9349   /* Parse args required to build the message */
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "del"))
9353         is_add = 0;
9354       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9355         ;
9356       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9357         ;
9358       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9359         v4_address_set = 1;
9360       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9361         v6_address_set = 1;
9362       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9363         v4_src_address_set = 1;
9364       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9365         v6_src_address_set = 1;
9366       else
9367         break;
9368     }
9369
9370   if (v4_address_set && v6_address_set)
9371     {
9372       errmsg ("both v4 and v6 server addresses set");
9373       return -99;
9374     }
9375   if (!v4_address_set && !v6_address_set)
9376     {
9377       errmsg ("no server addresses set");
9378       return -99;
9379     }
9380
9381   if (v4_src_address_set && v6_src_address_set)
9382     {
9383       errmsg ("both v4 and v6  src addresses set");
9384       return -99;
9385     }
9386   if (!v4_src_address_set && !v6_src_address_set)
9387     {
9388       errmsg ("no src addresses set");
9389       return -99;
9390     }
9391
9392   if (!(v4_src_address_set && v4_address_set) &&
9393       !(v6_src_address_set && v6_address_set))
9394     {
9395       errmsg ("no matching server and src addresses set");
9396       return -99;
9397     }
9398
9399   /* Construct the API message */
9400   M (DHCP_PROXY_CONFIG, mp);
9401
9402   mp->is_add = is_add;
9403   mp->rx_vrf_id = ntohl (rx_vrf_id);
9404   mp->server_vrf_id = ntohl (server_vrf_id);
9405   if (v6_address_set)
9406     {
9407       mp->is_ipv6 = 1;
9408       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9409       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9410     }
9411   else
9412     {
9413       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9414       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9415     }
9416
9417   /* send it... */
9418   S (mp);
9419
9420   /* Wait for a reply, return good/bad news  */
9421   W (ret);
9422   return ret;
9423 }
9424
9425 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9426 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9427
9428 static void
9429 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9430 {
9431   vat_main_t *vam = &vat_main;
9432   u32 i, count = mp->count;
9433   vl_api_dhcp_server_t *s;
9434
9435   if (mp->is_ipv6)
9436     print (vam->ofp,
9437            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9438            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9439            ntohl (mp->rx_vrf_id),
9440            format_ip6_address, mp->dhcp_src_address,
9441            mp->vss_type, mp->vss_vpn_ascii_id,
9442            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9443   else
9444     print (vam->ofp,
9445            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9446            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9447            ntohl (mp->rx_vrf_id),
9448            format_ip4_address, mp->dhcp_src_address,
9449            mp->vss_type, mp->vss_vpn_ascii_id,
9450            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9451
9452   for (i = 0; i < count; i++)
9453     {
9454       s = &mp->servers[i];
9455
9456       if (mp->is_ipv6)
9457         print (vam->ofp,
9458                " Server Table-ID %d, Server Address %U",
9459                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9460       else
9461         print (vam->ofp,
9462                " Server Table-ID %d, Server Address %U",
9463                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9464     }
9465 }
9466
9467 static void vl_api_dhcp_proxy_details_t_handler_json
9468   (vl_api_dhcp_proxy_details_t * mp)
9469 {
9470   vat_main_t *vam = &vat_main;
9471   vat_json_node_t *node = NULL;
9472   u32 i, count = mp->count;
9473   struct in_addr ip4;
9474   struct in6_addr ip6;
9475   vl_api_dhcp_server_t *s;
9476
9477   if (VAT_JSON_ARRAY != vam->json_tree.type)
9478     {
9479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9480       vat_json_init_array (&vam->json_tree);
9481     }
9482   node = vat_json_array_add (&vam->json_tree);
9483
9484   vat_json_init_object (node);
9485   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9486   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9487                              sizeof (mp->vss_type));
9488   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9489                                    mp->vss_vpn_ascii_id);
9490   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9491   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9492
9493   if (mp->is_ipv6)
9494     {
9495       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9496       vat_json_object_add_ip6 (node, "src_address", ip6);
9497     }
9498   else
9499     {
9500       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9501       vat_json_object_add_ip4 (node, "src_address", ip4);
9502     }
9503
9504   for (i = 0; i < count; i++)
9505     {
9506       s = &mp->servers[i];
9507
9508       vat_json_object_add_uint (node, "server-table-id",
9509                                 ntohl (s->server_vrf_id));
9510
9511       if (mp->is_ipv6)
9512         {
9513           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9514           vat_json_object_add_ip4 (node, "src_address", ip4);
9515         }
9516       else
9517         {
9518           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9519           vat_json_object_add_ip6 (node, "server_address", ip6);
9520         }
9521     }
9522 }
9523
9524 static int
9525 api_dhcp_proxy_dump (vat_main_t * vam)
9526 {
9527   unformat_input_t *i = vam->input;
9528   vl_api_control_ping_t *mp_ping;
9529   vl_api_dhcp_proxy_dump_t *mp;
9530   u8 is_ipv6 = 0;
9531   int ret;
9532
9533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9534     {
9535       if (unformat (i, "ipv6"))
9536         is_ipv6 = 1;
9537       else
9538         {
9539           clib_warning ("parse error '%U'", format_unformat_error, i);
9540           return -99;
9541         }
9542     }
9543
9544   M (DHCP_PROXY_DUMP, mp);
9545
9546   mp->is_ip6 = is_ipv6;
9547   S (mp);
9548
9549   /* Use a control ping for synchronization */
9550   MPING (CONTROL_PING, mp_ping);
9551   S (mp_ping);
9552
9553   W (ret);
9554   return ret;
9555 }
9556
9557 static int
9558 api_dhcp_proxy_set_vss (vat_main_t * vam)
9559 {
9560   unformat_input_t *i = vam->input;
9561   vl_api_dhcp_proxy_set_vss_t *mp;
9562   u8 is_ipv6 = 0;
9563   u8 is_add = 1;
9564   u32 tbl_id = ~0;
9565   u8 vss_type = VSS_TYPE_DEFAULT;
9566   u8 *vpn_ascii_id = 0;
9567   u32 oui = 0;
9568   u32 fib_id = 0;
9569   int ret;
9570
9571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9572     {
9573       if (unformat (i, "tbl_id %d", &tbl_id))
9574         ;
9575       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9576         vss_type = VSS_TYPE_ASCII;
9577       else if (unformat (i, "fib_id %d", &fib_id))
9578         vss_type = VSS_TYPE_VPN_ID;
9579       else if (unformat (i, "oui %d", &oui))
9580         vss_type = VSS_TYPE_VPN_ID;
9581       else if (unformat (i, "ipv6"))
9582         is_ipv6 = 1;
9583       else if (unformat (i, "del"))
9584         is_add = 0;
9585       else
9586         break;
9587     }
9588
9589   if (tbl_id == ~0)
9590     {
9591       errmsg ("missing tbl_id ");
9592       vec_free (vpn_ascii_id);
9593       return -99;
9594     }
9595
9596   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9597     {
9598       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9599       vec_free (vpn_ascii_id);
9600       return -99;
9601     }
9602
9603   M (DHCP_PROXY_SET_VSS, mp);
9604   mp->tbl_id = ntohl (tbl_id);
9605   mp->vss_type = vss_type;
9606   if (vpn_ascii_id)
9607     {
9608       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9609       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9610     }
9611   mp->vpn_index = ntohl (fib_id);
9612   mp->oui = ntohl (oui);
9613   mp->is_ipv6 = is_ipv6;
9614   mp->is_add = is_add;
9615
9616   S (mp);
9617   W (ret);
9618
9619   vec_free (vpn_ascii_id);
9620   return ret;
9621 }
9622
9623 static int
9624 api_dhcp_client_config (vat_main_t * vam)
9625 {
9626   unformat_input_t *i = vam->input;
9627   vl_api_dhcp_client_config_t *mp;
9628   u32 sw_if_index;
9629   u8 sw_if_index_set = 0;
9630   u8 is_add = 1;
9631   u8 *hostname = 0;
9632   u8 disable_event = 0;
9633   int ret;
9634
9635   /* Parse args required to build the message */
9636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9637     {
9638       if (unformat (i, "del"))
9639         is_add = 0;
9640       else
9641         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9642         sw_if_index_set = 1;
9643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9644         sw_if_index_set = 1;
9645       else if (unformat (i, "hostname %s", &hostname))
9646         ;
9647       else if (unformat (i, "disable_event"))
9648         disable_event = 1;
9649       else
9650         break;
9651     }
9652
9653   if (sw_if_index_set == 0)
9654     {
9655       errmsg ("missing interface name or sw_if_index");
9656       return -99;
9657     }
9658
9659   if (vec_len (hostname) > 63)
9660     {
9661       errmsg ("hostname too long");
9662     }
9663   vec_add1 (hostname, 0);
9664
9665   /* Construct the API message */
9666   M (DHCP_CLIENT_CONFIG, mp);
9667
9668   mp->is_add = is_add;
9669   mp->client.sw_if_index = htonl (sw_if_index);
9670   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9671   vec_free (hostname);
9672   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9673   mp->client.pid = htonl (getpid ());
9674
9675   /* send it... */
9676   S (mp);
9677
9678   /* Wait for a reply, return good/bad news  */
9679   W (ret);
9680   return ret;
9681 }
9682
9683 static int
9684 api_set_ip_flow_hash (vat_main_t * vam)
9685 {
9686   unformat_input_t *i = vam->input;
9687   vl_api_set_ip_flow_hash_t *mp;
9688   u32 vrf_id = 0;
9689   u8 is_ipv6 = 0;
9690   u8 vrf_id_set = 0;
9691   u8 src = 0;
9692   u8 dst = 0;
9693   u8 sport = 0;
9694   u8 dport = 0;
9695   u8 proto = 0;
9696   u8 reverse = 0;
9697   int ret;
9698
9699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9700     {
9701       if (unformat (i, "vrf %d", &vrf_id))
9702         vrf_id_set = 1;
9703       else if (unformat (i, "ipv6"))
9704         is_ipv6 = 1;
9705       else if (unformat (i, "src"))
9706         src = 1;
9707       else if (unformat (i, "dst"))
9708         dst = 1;
9709       else if (unformat (i, "sport"))
9710         sport = 1;
9711       else if (unformat (i, "dport"))
9712         dport = 1;
9713       else if (unformat (i, "proto"))
9714         proto = 1;
9715       else if (unformat (i, "reverse"))
9716         reverse = 1;
9717
9718       else
9719         {
9720           clib_warning ("parse error '%U'", format_unformat_error, i);
9721           return -99;
9722         }
9723     }
9724
9725   if (vrf_id_set == 0)
9726     {
9727       errmsg ("missing vrf id");
9728       return -99;
9729     }
9730
9731   M (SET_IP_FLOW_HASH, mp);
9732   mp->src = src;
9733   mp->dst = dst;
9734   mp->sport = sport;
9735   mp->dport = dport;
9736   mp->proto = proto;
9737   mp->reverse = reverse;
9738   mp->vrf_id = ntohl (vrf_id);
9739   mp->is_ipv6 = is_ipv6;
9740
9741   S (mp);
9742   W (ret);
9743   return ret;
9744 }
9745
9746 static int
9747 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9748 {
9749   unformat_input_t *i = vam->input;
9750   vl_api_sw_interface_ip6_enable_disable_t *mp;
9751   u32 sw_if_index;
9752   u8 sw_if_index_set = 0;
9753   u8 enable = 0;
9754   int ret;
9755
9756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9759         sw_if_index_set = 1;
9760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9761         sw_if_index_set = 1;
9762       else if (unformat (i, "enable"))
9763         enable = 1;
9764       else if (unformat (i, "disable"))
9765         enable = 0;
9766       else
9767         {
9768           clib_warning ("parse error '%U'", format_unformat_error, i);
9769           return -99;
9770         }
9771     }
9772
9773   if (sw_if_index_set == 0)
9774     {
9775       errmsg ("missing interface name or sw_if_index");
9776       return -99;
9777     }
9778
9779   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9780
9781   mp->sw_if_index = ntohl (sw_if_index);
9782   mp->enable = enable;
9783
9784   S (mp);
9785   W (ret);
9786   return ret;
9787 }
9788
9789 static int
9790 api_ip6nd_proxy_add_del (vat_main_t * vam)
9791 {
9792   unformat_input_t *i = vam->input;
9793   vl_api_ip6nd_proxy_add_del_t *mp;
9794   u32 sw_if_index = ~0;
9795   u8 v6_address_set = 0;
9796   vl_api_ip6_address_t v6address;
9797   u8 is_del = 0;
9798   int ret;
9799
9800   /* Parse args required to build the message */
9801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9802     {
9803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9804         ;
9805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9806         ;
9807       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9808         v6_address_set = 1;
9809       if (unformat (i, "del"))
9810         is_del = 1;
9811       else
9812         {
9813           clib_warning ("parse error '%U'", format_unformat_error, i);
9814           return -99;
9815         }
9816     }
9817
9818   if (sw_if_index == ~0)
9819     {
9820       errmsg ("missing interface name or sw_if_index");
9821       return -99;
9822     }
9823   if (!v6_address_set)
9824     {
9825       errmsg ("no address set");
9826       return -99;
9827     }
9828
9829   /* Construct the API message */
9830   M (IP6ND_PROXY_ADD_DEL, mp);
9831
9832   mp->is_del = is_del;
9833   mp->sw_if_index = ntohl (sw_if_index);
9834   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9835
9836   /* send it... */
9837   S (mp);
9838
9839   /* Wait for a reply, return good/bad news  */
9840   W (ret);
9841   return ret;
9842 }
9843
9844 static int
9845 api_ip6nd_proxy_dump (vat_main_t * vam)
9846 {
9847   vl_api_ip6nd_proxy_dump_t *mp;
9848   vl_api_control_ping_t *mp_ping;
9849   int ret;
9850
9851   M (IP6ND_PROXY_DUMP, mp);
9852
9853   S (mp);
9854
9855   /* Use a control ping for synchronization */
9856   MPING (CONTROL_PING, mp_ping);
9857   S (mp_ping);
9858
9859   W (ret);
9860   return ret;
9861 }
9862
9863 static void vl_api_ip6nd_proxy_details_t_handler
9864   (vl_api_ip6nd_proxy_details_t * mp)
9865 {
9866   vat_main_t *vam = &vat_main;
9867
9868   print (vam->ofp, "host %U sw_if_index %d",
9869          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9870 }
9871
9872 static void vl_api_ip6nd_proxy_details_t_handler_json
9873   (vl_api_ip6nd_proxy_details_t * mp)
9874 {
9875   vat_main_t *vam = &vat_main;
9876   struct in6_addr ip6;
9877   vat_json_node_t *node = NULL;
9878
9879   if (VAT_JSON_ARRAY != vam->json_tree.type)
9880     {
9881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9882       vat_json_init_array (&vam->json_tree);
9883     }
9884   node = vat_json_array_add (&vam->json_tree);
9885
9886   vat_json_init_object (node);
9887   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9888
9889   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9890   vat_json_object_add_ip6 (node, "host", ip6);
9891 }
9892
9893 static int
9894 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9895 {
9896   unformat_input_t *i = vam->input;
9897   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9898   u32 sw_if_index;
9899   u8 sw_if_index_set = 0;
9900   u8 v6_address_set = 0;
9901   vl_api_prefix_t pfx;
9902   u8 use_default = 0;
9903   u8 no_advertise = 0;
9904   u8 off_link = 0;
9905   u8 no_autoconfig = 0;
9906   u8 no_onlink = 0;
9907   u8 is_no = 0;
9908   u32 val_lifetime = 0;
9909   u32 pref_lifetime = 0;
9910   int ret;
9911
9912   /* Parse args required to build the message */
9913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9916         sw_if_index_set = 1;
9917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9920         v6_address_set = 1;
9921       else if (unformat (i, "val_life %d", &val_lifetime))
9922         ;
9923       else if (unformat (i, "pref_life %d", &pref_lifetime))
9924         ;
9925       else if (unformat (i, "def"))
9926         use_default = 1;
9927       else if (unformat (i, "noadv"))
9928         no_advertise = 1;
9929       else if (unformat (i, "offl"))
9930         off_link = 1;
9931       else if (unformat (i, "noauto"))
9932         no_autoconfig = 1;
9933       else if (unformat (i, "nolink"))
9934         no_onlink = 1;
9935       else if (unformat (i, "isno"))
9936         is_no = 1;
9937       else
9938         {
9939           clib_warning ("parse error '%U'", format_unformat_error, i);
9940           return -99;
9941         }
9942     }
9943
9944   if (sw_if_index_set == 0)
9945     {
9946       errmsg ("missing interface name or sw_if_index");
9947       return -99;
9948     }
9949   if (!v6_address_set)
9950     {
9951       errmsg ("no address set");
9952       return -99;
9953     }
9954
9955   /* Construct the API message */
9956   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9957
9958   mp->sw_if_index = ntohl (sw_if_index);
9959   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9960   mp->use_default = use_default;
9961   mp->no_advertise = no_advertise;
9962   mp->off_link = off_link;
9963   mp->no_autoconfig = no_autoconfig;
9964   mp->no_onlink = no_onlink;
9965   mp->is_no = is_no;
9966   mp->val_lifetime = ntohl (val_lifetime);
9967   mp->pref_lifetime = ntohl (pref_lifetime);
9968
9969   /* send it... */
9970   S (mp);
9971
9972   /* Wait for a reply, return good/bad news  */
9973   W (ret);
9974   return ret;
9975 }
9976
9977 static int
9978 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9979 {
9980   unformat_input_t *i = vam->input;
9981   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9982   u32 sw_if_index;
9983   u8 sw_if_index_set = 0;
9984   u8 suppress = 0;
9985   u8 managed = 0;
9986   u8 other = 0;
9987   u8 ll_option = 0;
9988   u8 send_unicast = 0;
9989   u8 cease = 0;
9990   u8 is_no = 0;
9991   u8 default_router = 0;
9992   u32 max_interval = 0;
9993   u32 min_interval = 0;
9994   u32 lifetime = 0;
9995   u32 initial_count = 0;
9996   u32 initial_interval = 0;
9997   int ret;
9998
9999
10000   /* Parse args required to build the message */
10001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10002     {
10003       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10004         sw_if_index_set = 1;
10005       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10006         sw_if_index_set = 1;
10007       else if (unformat (i, "maxint %d", &max_interval))
10008         ;
10009       else if (unformat (i, "minint %d", &min_interval))
10010         ;
10011       else if (unformat (i, "life %d", &lifetime))
10012         ;
10013       else if (unformat (i, "count %d", &initial_count))
10014         ;
10015       else if (unformat (i, "interval %d", &initial_interval))
10016         ;
10017       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10018         suppress = 1;
10019       else if (unformat (i, "managed"))
10020         managed = 1;
10021       else if (unformat (i, "other"))
10022         other = 1;
10023       else if (unformat (i, "ll"))
10024         ll_option = 1;
10025       else if (unformat (i, "send"))
10026         send_unicast = 1;
10027       else if (unformat (i, "cease"))
10028         cease = 1;
10029       else if (unformat (i, "isno"))
10030         is_no = 1;
10031       else if (unformat (i, "def"))
10032         default_router = 1;
10033       else
10034         {
10035           clib_warning ("parse error '%U'", format_unformat_error, i);
10036           return -99;
10037         }
10038     }
10039
10040   if (sw_if_index_set == 0)
10041     {
10042       errmsg ("missing interface name or sw_if_index");
10043       return -99;
10044     }
10045
10046   /* Construct the API message */
10047   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10048
10049   mp->sw_if_index = ntohl (sw_if_index);
10050   mp->max_interval = ntohl (max_interval);
10051   mp->min_interval = ntohl (min_interval);
10052   mp->lifetime = ntohl (lifetime);
10053   mp->initial_count = ntohl (initial_count);
10054   mp->initial_interval = ntohl (initial_interval);
10055   mp->suppress = suppress;
10056   mp->managed = managed;
10057   mp->other = other;
10058   mp->ll_option = ll_option;
10059   mp->send_unicast = send_unicast;
10060   mp->cease = cease;
10061   mp->is_no = is_no;
10062   mp->default_router = default_router;
10063
10064   /* send it... */
10065   S (mp);
10066
10067   /* Wait for a reply, return good/bad news  */
10068   W (ret);
10069   return ret;
10070 }
10071
10072 static int
10073 api_set_arp_neighbor_limit (vat_main_t * vam)
10074 {
10075   unformat_input_t *i = vam->input;
10076   vl_api_set_arp_neighbor_limit_t *mp;
10077   u32 arp_nbr_limit;
10078   u8 limit_set = 0;
10079   u8 is_ipv6 = 0;
10080   int ret;
10081
10082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10083     {
10084       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10085         limit_set = 1;
10086       else if (unformat (i, "ipv6"))
10087         is_ipv6 = 1;
10088       else
10089         {
10090           clib_warning ("parse error '%U'", format_unformat_error, i);
10091           return -99;
10092         }
10093     }
10094
10095   if (limit_set == 0)
10096     {
10097       errmsg ("missing limit value");
10098       return -99;
10099     }
10100
10101   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10102
10103   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10104   mp->is_ipv6 = is_ipv6;
10105
10106   S (mp);
10107   W (ret);
10108   return ret;
10109 }
10110
10111 static int
10112 api_l2_patch_add_del (vat_main_t * vam)
10113 {
10114   unformat_input_t *i = vam->input;
10115   vl_api_l2_patch_add_del_t *mp;
10116   u32 rx_sw_if_index;
10117   u8 rx_sw_if_index_set = 0;
10118   u32 tx_sw_if_index;
10119   u8 tx_sw_if_index_set = 0;
10120   u8 is_add = 1;
10121   int ret;
10122
10123   /* Parse args required to build the message */
10124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10125     {
10126       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10127         rx_sw_if_index_set = 1;
10128       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10129         tx_sw_if_index_set = 1;
10130       else if (unformat (i, "rx"))
10131         {
10132           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10133             {
10134               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10135                             &rx_sw_if_index))
10136                 rx_sw_if_index_set = 1;
10137             }
10138           else
10139             break;
10140         }
10141       else if (unformat (i, "tx"))
10142         {
10143           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144             {
10145               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10146                             &tx_sw_if_index))
10147                 tx_sw_if_index_set = 1;
10148             }
10149           else
10150             break;
10151         }
10152       else if (unformat (i, "del"))
10153         is_add = 0;
10154       else
10155         break;
10156     }
10157
10158   if (rx_sw_if_index_set == 0)
10159     {
10160       errmsg ("missing rx interface name or rx_sw_if_index");
10161       return -99;
10162     }
10163
10164   if (tx_sw_if_index_set == 0)
10165     {
10166       errmsg ("missing tx interface name or tx_sw_if_index");
10167       return -99;
10168     }
10169
10170   M (L2_PATCH_ADD_DEL, mp);
10171
10172   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10173   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10174   mp->is_add = is_add;
10175
10176   S (mp);
10177   W (ret);
10178   return ret;
10179 }
10180
10181 u8 is_del;
10182 u8 localsid_addr[16];
10183 u8 end_psp;
10184 u8 behavior;
10185 u32 sw_if_index;
10186 u32 vlan_index;
10187 u32 fib_table;
10188 u8 nh_addr[16];
10189
10190 static int
10191 api_sr_localsid_add_del (vat_main_t * vam)
10192 {
10193   unformat_input_t *i = vam->input;
10194   vl_api_sr_localsid_add_del_t *mp;
10195
10196   u8 is_del;
10197   ip6_address_t localsid;
10198   u8 end_psp = 0;
10199   u8 behavior = ~0;
10200   u32 sw_if_index;
10201   u32 fib_table = ~(u32) 0;
10202   ip6_address_t nh_addr6;
10203   ip4_address_t nh_addr4;
10204   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10205   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10206
10207   bool nexthop_set = 0;
10208
10209   int ret;
10210
10211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10212     {
10213       if (unformat (i, "del"))
10214         is_del = 1;
10215       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10216       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10217         nexthop_set = 1;
10218       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10219         nexthop_set = 1;
10220       else if (unformat (i, "behavior %u", &behavior));
10221       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10222       else if (unformat (i, "fib-table %u", &fib_table));
10223       else if (unformat (i, "end.psp %u", &behavior));
10224       else
10225         break;
10226     }
10227
10228   M (SR_LOCALSID_ADD_DEL, mp);
10229
10230   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10231   if (nexthop_set)
10232     {
10233       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10234       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10235     }
10236   mp->behavior = behavior;
10237   mp->sw_if_index = ntohl (sw_if_index);
10238   mp->fib_table = ntohl (fib_table);
10239   mp->end_psp = end_psp;
10240   mp->is_del = is_del;
10241
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 static int
10248 api_ioam_enable (vat_main_t * vam)
10249 {
10250   unformat_input_t *input = vam->input;
10251   vl_api_ioam_enable_t *mp;
10252   u32 id = 0;
10253   int has_trace_option = 0;
10254   int has_pot_option = 0;
10255   int has_seqno_option = 0;
10256   int has_analyse_option = 0;
10257   int ret;
10258
10259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10260     {
10261       if (unformat (input, "trace"))
10262         has_trace_option = 1;
10263       else if (unformat (input, "pot"))
10264         has_pot_option = 1;
10265       else if (unformat (input, "seqno"))
10266         has_seqno_option = 1;
10267       else if (unformat (input, "analyse"))
10268         has_analyse_option = 1;
10269       else
10270         break;
10271     }
10272   M (IOAM_ENABLE, mp);
10273   mp->id = htons (id);
10274   mp->seqno = has_seqno_option;
10275   mp->analyse = has_analyse_option;
10276   mp->pot_enable = has_pot_option;
10277   mp->trace_enable = has_trace_option;
10278
10279   S (mp);
10280   W (ret);
10281   return ret;
10282 }
10283
10284
10285 static int
10286 api_ioam_disable (vat_main_t * vam)
10287 {
10288   vl_api_ioam_disable_t *mp;
10289   int ret;
10290
10291   M (IOAM_DISABLE, mp);
10292   S (mp);
10293   W (ret);
10294   return ret;
10295 }
10296
10297 #define foreach_tcp_proto_field                 \
10298 _(src_port)                                     \
10299 _(dst_port)
10300
10301 #define foreach_udp_proto_field                 \
10302 _(src_port)                                     \
10303 _(dst_port)
10304
10305 #define foreach_ip4_proto_field                 \
10306 _(src_address)                                  \
10307 _(dst_address)                                  \
10308 _(tos)                                          \
10309 _(length)                                       \
10310 _(fragment_id)                                  \
10311 _(ttl)                                          \
10312 _(protocol)                                     \
10313 _(checksum)
10314
10315 typedef struct
10316 {
10317   u16 src_port, dst_port;
10318 } tcpudp_header_t;
10319
10320 #if VPP_API_TEST_BUILTIN == 0
10321 uword
10322 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10323 {
10324   u8 **maskp = va_arg (*args, u8 **);
10325   u8 *mask = 0;
10326   u8 found_something = 0;
10327   tcp_header_t *tcp;
10328
10329 #define _(a) u8 a=0;
10330   foreach_tcp_proto_field;
10331 #undef _
10332
10333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10334     {
10335       if (0);
10336 #define _(a) else if (unformat (input, #a)) a=1;
10337       foreach_tcp_proto_field
10338 #undef _
10339         else
10340         break;
10341     }
10342
10343 #define _(a) found_something += a;
10344   foreach_tcp_proto_field;
10345 #undef _
10346
10347   if (found_something == 0)
10348     return 0;
10349
10350   vec_validate (mask, sizeof (*tcp) - 1);
10351
10352   tcp = (tcp_header_t *) mask;
10353
10354 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10355   foreach_tcp_proto_field;
10356 #undef _
10357
10358   *maskp = mask;
10359   return 1;
10360 }
10361
10362 uword
10363 unformat_udp_mask (unformat_input_t * input, va_list * args)
10364 {
10365   u8 **maskp = va_arg (*args, u8 **);
10366   u8 *mask = 0;
10367   u8 found_something = 0;
10368   udp_header_t *udp;
10369
10370 #define _(a) u8 a=0;
10371   foreach_udp_proto_field;
10372 #undef _
10373
10374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10375     {
10376       if (0);
10377 #define _(a) else if (unformat (input, #a)) a=1;
10378       foreach_udp_proto_field
10379 #undef _
10380         else
10381         break;
10382     }
10383
10384 #define _(a) found_something += a;
10385   foreach_udp_proto_field;
10386 #undef _
10387
10388   if (found_something == 0)
10389     return 0;
10390
10391   vec_validate (mask, sizeof (*udp) - 1);
10392
10393   udp = (udp_header_t *) mask;
10394
10395 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10396   foreach_udp_proto_field;
10397 #undef _
10398
10399   *maskp = mask;
10400   return 1;
10401 }
10402
10403 uword
10404 unformat_l4_mask (unformat_input_t * input, va_list * args)
10405 {
10406   u8 **maskp = va_arg (*args, u8 **);
10407   u16 src_port = 0, dst_port = 0;
10408   tcpudp_header_t *tcpudp;
10409
10410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10411     {
10412       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10413         return 1;
10414       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10415         return 1;
10416       else if (unformat (input, "src_port"))
10417         src_port = 0xFFFF;
10418       else if (unformat (input, "dst_port"))
10419         dst_port = 0xFFFF;
10420       else
10421         return 0;
10422     }
10423
10424   if (!src_port && !dst_port)
10425     return 0;
10426
10427   u8 *mask = 0;
10428   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10429
10430   tcpudp = (tcpudp_header_t *) mask;
10431   tcpudp->src_port = src_port;
10432   tcpudp->dst_port = dst_port;
10433
10434   *maskp = mask;
10435
10436   return 1;
10437 }
10438
10439 uword
10440 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10441 {
10442   u8 **maskp = va_arg (*args, u8 **);
10443   u8 *mask = 0;
10444   u8 found_something = 0;
10445   ip4_header_t *ip;
10446
10447 #define _(a) u8 a=0;
10448   foreach_ip4_proto_field;
10449 #undef _
10450   u8 version = 0;
10451   u8 hdr_length = 0;
10452
10453
10454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10455     {
10456       if (unformat (input, "version"))
10457         version = 1;
10458       else if (unformat (input, "hdr_length"))
10459         hdr_length = 1;
10460       else if (unformat (input, "src"))
10461         src_address = 1;
10462       else if (unformat (input, "dst"))
10463         dst_address = 1;
10464       else if (unformat (input, "proto"))
10465         protocol = 1;
10466
10467 #define _(a) else if (unformat (input, #a)) a=1;
10468       foreach_ip4_proto_field
10469 #undef _
10470         else
10471         break;
10472     }
10473
10474 #define _(a) found_something += a;
10475   foreach_ip4_proto_field;
10476 #undef _
10477
10478   if (found_something == 0)
10479     return 0;
10480
10481   vec_validate (mask, sizeof (*ip) - 1);
10482
10483   ip = (ip4_header_t *) mask;
10484
10485 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10486   foreach_ip4_proto_field;
10487 #undef _
10488
10489   ip->ip_version_and_header_length = 0;
10490
10491   if (version)
10492     ip->ip_version_and_header_length |= 0xF0;
10493
10494   if (hdr_length)
10495     ip->ip_version_and_header_length |= 0x0F;
10496
10497   *maskp = mask;
10498   return 1;
10499 }
10500
10501 #define foreach_ip6_proto_field                 \
10502 _(src_address)                                  \
10503 _(dst_address)                                  \
10504 _(payload_length)                               \
10505 _(hop_limit)                                    \
10506 _(protocol)
10507
10508 uword
10509 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10510 {
10511   u8 **maskp = va_arg (*args, u8 **);
10512   u8 *mask = 0;
10513   u8 found_something = 0;
10514   ip6_header_t *ip;
10515   u32 ip_version_traffic_class_and_flow_label;
10516
10517 #define _(a) u8 a=0;
10518   foreach_ip6_proto_field;
10519 #undef _
10520   u8 version = 0;
10521   u8 traffic_class = 0;
10522   u8 flow_label = 0;
10523
10524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10525     {
10526       if (unformat (input, "version"))
10527         version = 1;
10528       else if (unformat (input, "traffic-class"))
10529         traffic_class = 1;
10530       else if (unformat (input, "flow-label"))
10531         flow_label = 1;
10532       else if (unformat (input, "src"))
10533         src_address = 1;
10534       else if (unformat (input, "dst"))
10535         dst_address = 1;
10536       else if (unformat (input, "proto"))
10537         protocol = 1;
10538
10539 #define _(a) else if (unformat (input, #a)) a=1;
10540       foreach_ip6_proto_field
10541 #undef _
10542         else
10543         break;
10544     }
10545
10546 #define _(a) found_something += a;
10547   foreach_ip6_proto_field;
10548 #undef _
10549
10550   if (found_something == 0)
10551     return 0;
10552
10553   vec_validate (mask, sizeof (*ip) - 1);
10554
10555   ip = (ip6_header_t *) mask;
10556
10557 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10558   foreach_ip6_proto_field;
10559 #undef _
10560
10561   ip_version_traffic_class_and_flow_label = 0;
10562
10563   if (version)
10564     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10565
10566   if (traffic_class)
10567     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10568
10569   if (flow_label)
10570     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10571
10572   ip->ip_version_traffic_class_and_flow_label =
10573     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10574
10575   *maskp = mask;
10576   return 1;
10577 }
10578
10579 uword
10580 unformat_l3_mask (unformat_input_t * input, va_list * args)
10581 {
10582   u8 **maskp = va_arg (*args, u8 **);
10583
10584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10585     {
10586       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10587         return 1;
10588       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10589         return 1;
10590       else
10591         break;
10592     }
10593   return 0;
10594 }
10595
10596 uword
10597 unformat_l2_mask (unformat_input_t * input, va_list * args)
10598 {
10599   u8 **maskp = va_arg (*args, u8 **);
10600   u8 *mask = 0;
10601   u8 src = 0;
10602   u8 dst = 0;
10603   u8 proto = 0;
10604   u8 tag1 = 0;
10605   u8 tag2 = 0;
10606   u8 ignore_tag1 = 0;
10607   u8 ignore_tag2 = 0;
10608   u8 cos1 = 0;
10609   u8 cos2 = 0;
10610   u8 dot1q = 0;
10611   u8 dot1ad = 0;
10612   int len = 14;
10613
10614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10615     {
10616       if (unformat (input, "src"))
10617         src = 1;
10618       else if (unformat (input, "dst"))
10619         dst = 1;
10620       else if (unformat (input, "proto"))
10621         proto = 1;
10622       else if (unformat (input, "tag1"))
10623         tag1 = 1;
10624       else if (unformat (input, "tag2"))
10625         tag2 = 1;
10626       else if (unformat (input, "ignore-tag1"))
10627         ignore_tag1 = 1;
10628       else if (unformat (input, "ignore-tag2"))
10629         ignore_tag2 = 1;
10630       else if (unformat (input, "cos1"))
10631         cos1 = 1;
10632       else if (unformat (input, "cos2"))
10633         cos2 = 1;
10634       else if (unformat (input, "dot1q"))
10635         dot1q = 1;
10636       else if (unformat (input, "dot1ad"))
10637         dot1ad = 1;
10638       else
10639         break;
10640     }
10641   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10642        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10643     return 0;
10644
10645   if (tag1 || ignore_tag1 || cos1 || dot1q)
10646     len = 18;
10647   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10648     len = 22;
10649
10650   vec_validate (mask, len - 1);
10651
10652   if (dst)
10653     clib_memset (mask, 0xff, 6);
10654
10655   if (src)
10656     clib_memset (mask + 6, 0xff, 6);
10657
10658   if (tag2 || dot1ad)
10659     {
10660       /* inner vlan tag */
10661       if (tag2)
10662         {
10663           mask[19] = 0xff;
10664           mask[18] = 0x0f;
10665         }
10666       if (cos2)
10667         mask[18] |= 0xe0;
10668       if (proto)
10669         mask[21] = mask[20] = 0xff;
10670       if (tag1)
10671         {
10672           mask[15] = 0xff;
10673           mask[14] = 0x0f;
10674         }
10675       if (cos1)
10676         mask[14] |= 0xe0;
10677       *maskp = mask;
10678       return 1;
10679     }
10680   if (tag1 | dot1q)
10681     {
10682       if (tag1)
10683         {
10684           mask[15] = 0xff;
10685           mask[14] = 0x0f;
10686         }
10687       if (cos1)
10688         mask[14] |= 0xe0;
10689       if (proto)
10690         mask[16] = mask[17] = 0xff;
10691
10692       *maskp = mask;
10693       return 1;
10694     }
10695   if (cos2)
10696     mask[18] |= 0xe0;
10697   if (cos1)
10698     mask[14] |= 0xe0;
10699   if (proto)
10700     mask[12] = mask[13] = 0xff;
10701
10702   *maskp = mask;
10703   return 1;
10704 }
10705
10706 uword
10707 unformat_classify_mask (unformat_input_t * input, va_list * args)
10708 {
10709   u8 **maskp = va_arg (*args, u8 **);
10710   u32 *skipp = va_arg (*args, u32 *);
10711   u32 *matchp = va_arg (*args, u32 *);
10712   u32 match;
10713   u8 *mask = 0;
10714   u8 *l2 = 0;
10715   u8 *l3 = 0;
10716   u8 *l4 = 0;
10717   int i;
10718
10719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10720     {
10721       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10722         ;
10723       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10724         ;
10725       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10726         ;
10727       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10728         ;
10729       else
10730         break;
10731     }
10732
10733   if (l4 && !l3)
10734     {
10735       vec_free (mask);
10736       vec_free (l2);
10737       vec_free (l4);
10738       return 0;
10739     }
10740
10741   if (mask || l2 || l3 || l4)
10742     {
10743       if (l2 || l3 || l4)
10744         {
10745           /* "With a free Ethernet header in every package" */
10746           if (l2 == 0)
10747             vec_validate (l2, 13);
10748           mask = l2;
10749           if (vec_len (l3))
10750             {
10751               vec_append (mask, l3);
10752               vec_free (l3);
10753             }
10754           if (vec_len (l4))
10755             {
10756               vec_append (mask, l4);
10757               vec_free (l4);
10758             }
10759         }
10760
10761       /* Scan forward looking for the first significant mask octet */
10762       for (i = 0; i < vec_len (mask); i++)
10763         if (mask[i])
10764           break;
10765
10766       /* compute (skip, match) params */
10767       *skipp = i / sizeof (u32x4);
10768       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10769
10770       /* Pad mask to an even multiple of the vector size */
10771       while (vec_len (mask) % sizeof (u32x4))
10772         vec_add1 (mask, 0);
10773
10774       match = vec_len (mask) / sizeof (u32x4);
10775
10776       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10777         {
10778           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10779           if (*tmp || *(tmp + 1))
10780             break;
10781           match--;
10782         }
10783       if (match == 0)
10784         clib_warning ("BUG: match 0");
10785
10786       _vec_len (mask) = match * sizeof (u32x4);
10787
10788       *matchp = match;
10789       *maskp = mask;
10790
10791       return 1;
10792     }
10793
10794   return 0;
10795 }
10796 #endif /* VPP_API_TEST_BUILTIN */
10797
10798 #define foreach_l2_next                         \
10799 _(drop, DROP)                                   \
10800 _(ethernet, ETHERNET_INPUT)                     \
10801 _(ip4, IP4_INPUT)                               \
10802 _(ip6, IP6_INPUT)
10803
10804 uword
10805 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10806 {
10807   u32 *miss_next_indexp = va_arg (*args, u32 *);
10808   u32 next_index = 0;
10809   u32 tmp;
10810
10811 #define _(n,N) \
10812   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10813   foreach_l2_next;
10814 #undef _
10815
10816   if (unformat (input, "%d", &tmp))
10817     {
10818       next_index = tmp;
10819       goto out;
10820     }
10821
10822   return 0;
10823
10824 out:
10825   *miss_next_indexp = next_index;
10826   return 1;
10827 }
10828
10829 #define foreach_ip_next                         \
10830 _(drop, DROP)                                   \
10831 _(local, LOCAL)                                 \
10832 _(rewrite, REWRITE)
10833
10834 uword
10835 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10836 {
10837   u32 *miss_next_indexp = va_arg (*args, u32 *);
10838   u32 next_index = 0;
10839   u32 tmp;
10840
10841 #define _(n,N) \
10842   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10843   foreach_ip_next;
10844 #undef _
10845
10846   if (unformat (input, "%d", &tmp))
10847     {
10848       next_index = tmp;
10849       goto out;
10850     }
10851
10852   return 0;
10853
10854 out:
10855   *miss_next_indexp = next_index;
10856   return 1;
10857 }
10858
10859 #define foreach_acl_next                        \
10860 _(deny, DENY)
10861
10862 uword
10863 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10864 {
10865   u32 *miss_next_indexp = va_arg (*args, u32 *);
10866   u32 next_index = 0;
10867   u32 tmp;
10868
10869 #define _(n,N) \
10870   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10871   foreach_acl_next;
10872 #undef _
10873
10874   if (unformat (input, "permit"))
10875     {
10876       next_index = ~0;
10877       goto out;
10878     }
10879   else if (unformat (input, "%d", &tmp))
10880     {
10881       next_index = tmp;
10882       goto out;
10883     }
10884
10885   return 0;
10886
10887 out:
10888   *miss_next_indexp = next_index;
10889   return 1;
10890 }
10891
10892 uword
10893 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10894 {
10895   u32 *r = va_arg (*args, u32 *);
10896
10897   if (unformat (input, "conform-color"))
10898     *r = POLICE_CONFORM;
10899   else if (unformat (input, "exceed-color"))
10900     *r = POLICE_EXCEED;
10901   else
10902     return 0;
10903
10904   return 1;
10905 }
10906
10907 static int
10908 api_classify_add_del_table (vat_main_t * vam)
10909 {
10910   unformat_input_t *i = vam->input;
10911   vl_api_classify_add_del_table_t *mp;
10912
10913   u32 nbuckets = 2;
10914   u32 skip = ~0;
10915   u32 match = ~0;
10916   int is_add = 1;
10917   int del_chain = 0;
10918   u32 table_index = ~0;
10919   u32 next_table_index = ~0;
10920   u32 miss_next_index = ~0;
10921   u32 memory_size = 32 << 20;
10922   u8 *mask = 0;
10923   u32 current_data_flag = 0;
10924   int current_data_offset = 0;
10925   int ret;
10926
10927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10928     {
10929       if (unformat (i, "del"))
10930         is_add = 0;
10931       else if (unformat (i, "del-chain"))
10932         {
10933           is_add = 0;
10934           del_chain = 1;
10935         }
10936       else if (unformat (i, "buckets %d", &nbuckets))
10937         ;
10938       else if (unformat (i, "memory_size %d", &memory_size))
10939         ;
10940       else if (unformat (i, "skip %d", &skip))
10941         ;
10942       else if (unformat (i, "match %d", &match))
10943         ;
10944       else if (unformat (i, "table %d", &table_index))
10945         ;
10946       else if (unformat (i, "mask %U", unformat_classify_mask,
10947                          &mask, &skip, &match))
10948         ;
10949       else if (unformat (i, "next-table %d", &next_table_index))
10950         ;
10951       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10952                          &miss_next_index))
10953         ;
10954       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10955                          &miss_next_index))
10956         ;
10957       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10958                          &miss_next_index))
10959         ;
10960       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10961         ;
10962       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10963         ;
10964       else
10965         break;
10966     }
10967
10968   if (is_add && mask == 0)
10969     {
10970       errmsg ("Mask required");
10971       return -99;
10972     }
10973
10974   if (is_add && skip == ~0)
10975     {
10976       errmsg ("skip count required");
10977       return -99;
10978     }
10979
10980   if (is_add && match == ~0)
10981     {
10982       errmsg ("match count required");
10983       return -99;
10984     }
10985
10986   if (!is_add && table_index == ~0)
10987     {
10988       errmsg ("table index required for delete");
10989       return -99;
10990     }
10991
10992   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10993
10994   mp->is_add = is_add;
10995   mp->del_chain = del_chain;
10996   mp->table_index = ntohl (table_index);
10997   mp->nbuckets = ntohl (nbuckets);
10998   mp->memory_size = ntohl (memory_size);
10999   mp->skip_n_vectors = ntohl (skip);
11000   mp->match_n_vectors = ntohl (match);
11001   mp->next_table_index = ntohl (next_table_index);
11002   mp->miss_next_index = ntohl (miss_next_index);
11003   mp->current_data_flag = ntohl (current_data_flag);
11004   mp->current_data_offset = ntohl (current_data_offset);
11005   mp->mask_len = ntohl (vec_len (mask));
11006   clib_memcpy (mp->mask, mask, vec_len (mask));
11007
11008   vec_free (mask);
11009
11010   S (mp);
11011   W (ret);
11012   return ret;
11013 }
11014
11015 #if VPP_API_TEST_BUILTIN == 0
11016 uword
11017 unformat_l4_match (unformat_input_t * input, va_list * args)
11018 {
11019   u8 **matchp = va_arg (*args, u8 **);
11020
11021   u8 *proto_header = 0;
11022   int src_port = 0;
11023   int dst_port = 0;
11024
11025   tcpudp_header_t h;
11026
11027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (input, "src_port %d", &src_port))
11030         ;
11031       else if (unformat (input, "dst_port %d", &dst_port))
11032         ;
11033       else
11034         return 0;
11035     }
11036
11037   h.src_port = clib_host_to_net_u16 (src_port);
11038   h.dst_port = clib_host_to_net_u16 (dst_port);
11039   vec_validate (proto_header, sizeof (h) - 1);
11040   memcpy (proto_header, &h, sizeof (h));
11041
11042   *matchp = proto_header;
11043
11044   return 1;
11045 }
11046
11047 uword
11048 unformat_ip4_match (unformat_input_t * input, va_list * args)
11049 {
11050   u8 **matchp = va_arg (*args, u8 **);
11051   u8 *match = 0;
11052   ip4_header_t *ip;
11053   int version = 0;
11054   u32 version_val;
11055   int hdr_length = 0;
11056   u32 hdr_length_val;
11057   int src = 0, dst = 0;
11058   ip4_address_t src_val, dst_val;
11059   int proto = 0;
11060   u32 proto_val;
11061   int tos = 0;
11062   u32 tos_val;
11063   int length = 0;
11064   u32 length_val;
11065   int fragment_id = 0;
11066   u32 fragment_id_val;
11067   int ttl = 0;
11068   int ttl_val;
11069   int checksum = 0;
11070   u32 checksum_val;
11071
11072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11073     {
11074       if (unformat (input, "version %d", &version_val))
11075         version = 1;
11076       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11077         hdr_length = 1;
11078       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11079         src = 1;
11080       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11081         dst = 1;
11082       else if (unformat (input, "proto %d", &proto_val))
11083         proto = 1;
11084       else if (unformat (input, "tos %d", &tos_val))
11085         tos = 1;
11086       else if (unformat (input, "length %d", &length_val))
11087         length = 1;
11088       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11089         fragment_id = 1;
11090       else if (unformat (input, "ttl %d", &ttl_val))
11091         ttl = 1;
11092       else if (unformat (input, "checksum %d", &checksum_val))
11093         checksum = 1;
11094       else
11095         break;
11096     }
11097
11098   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11099       + ttl + checksum == 0)
11100     return 0;
11101
11102   /*
11103    * Aligned because we use the real comparison functions
11104    */
11105   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11106
11107   ip = (ip4_header_t *) match;
11108
11109   /* These are realistically matched in practice */
11110   if (src)
11111     ip->src_address.as_u32 = src_val.as_u32;
11112
11113   if (dst)
11114     ip->dst_address.as_u32 = dst_val.as_u32;
11115
11116   if (proto)
11117     ip->protocol = proto_val;
11118
11119
11120   /* These are not, but they're included for completeness */
11121   if (version)
11122     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11123
11124   if (hdr_length)
11125     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11126
11127   if (tos)
11128     ip->tos = tos_val;
11129
11130   if (length)
11131     ip->length = clib_host_to_net_u16 (length_val);
11132
11133   if (ttl)
11134     ip->ttl = ttl_val;
11135
11136   if (checksum)
11137     ip->checksum = clib_host_to_net_u16 (checksum_val);
11138
11139   *matchp = match;
11140   return 1;
11141 }
11142
11143 uword
11144 unformat_ip6_match (unformat_input_t * input, va_list * args)
11145 {
11146   u8 **matchp = va_arg (*args, u8 **);
11147   u8 *match = 0;
11148   ip6_header_t *ip;
11149   int version = 0;
11150   u32 version_val;
11151   u8 traffic_class = 0;
11152   u32 traffic_class_val = 0;
11153   u8 flow_label = 0;
11154   u8 flow_label_val;
11155   int src = 0, dst = 0;
11156   ip6_address_t src_val, dst_val;
11157   int proto = 0;
11158   u32 proto_val;
11159   int payload_length = 0;
11160   u32 payload_length_val;
11161   int hop_limit = 0;
11162   int hop_limit_val;
11163   u32 ip_version_traffic_class_and_flow_label;
11164
11165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11166     {
11167       if (unformat (input, "version %d", &version_val))
11168         version = 1;
11169       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11170         traffic_class = 1;
11171       else if (unformat (input, "flow_label %d", &flow_label_val))
11172         flow_label = 1;
11173       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11174         src = 1;
11175       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11176         dst = 1;
11177       else if (unformat (input, "proto %d", &proto_val))
11178         proto = 1;
11179       else if (unformat (input, "payload_length %d", &payload_length_val))
11180         payload_length = 1;
11181       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11182         hop_limit = 1;
11183       else
11184         break;
11185     }
11186
11187   if (version + traffic_class + flow_label + src + dst + proto +
11188       payload_length + hop_limit == 0)
11189     return 0;
11190
11191   /*
11192    * Aligned because we use the real comparison functions
11193    */
11194   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11195
11196   ip = (ip6_header_t *) match;
11197
11198   if (src)
11199     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11200
11201   if (dst)
11202     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11203
11204   if (proto)
11205     ip->protocol = proto_val;
11206
11207   ip_version_traffic_class_and_flow_label = 0;
11208
11209   if (version)
11210     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11211
11212   if (traffic_class)
11213     ip_version_traffic_class_and_flow_label |=
11214       (traffic_class_val & 0xFF) << 20;
11215
11216   if (flow_label)
11217     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11218
11219   ip->ip_version_traffic_class_and_flow_label =
11220     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11221
11222   if (payload_length)
11223     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11224
11225   if (hop_limit)
11226     ip->hop_limit = hop_limit_val;
11227
11228   *matchp = match;
11229   return 1;
11230 }
11231
11232 uword
11233 unformat_l3_match (unformat_input_t * input, va_list * args)
11234 {
11235   u8 **matchp = va_arg (*args, u8 **);
11236
11237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11240         return 1;
11241       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11242         return 1;
11243       else
11244         break;
11245     }
11246   return 0;
11247 }
11248
11249 uword
11250 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11251 {
11252   u8 *tagp = va_arg (*args, u8 *);
11253   u32 tag;
11254
11255   if (unformat (input, "%d", &tag))
11256     {
11257       tagp[0] = (tag >> 8) & 0x0F;
11258       tagp[1] = tag & 0xFF;
11259       return 1;
11260     }
11261
11262   return 0;
11263 }
11264
11265 uword
11266 unformat_l2_match (unformat_input_t * input, va_list * args)
11267 {
11268   u8 **matchp = va_arg (*args, u8 **);
11269   u8 *match = 0;
11270   u8 src = 0;
11271   u8 src_val[6];
11272   u8 dst = 0;
11273   u8 dst_val[6];
11274   u8 proto = 0;
11275   u16 proto_val;
11276   u8 tag1 = 0;
11277   u8 tag1_val[2];
11278   u8 tag2 = 0;
11279   u8 tag2_val[2];
11280   int len = 14;
11281   u8 ignore_tag1 = 0;
11282   u8 ignore_tag2 = 0;
11283   u8 cos1 = 0;
11284   u8 cos2 = 0;
11285   u32 cos1_val = 0;
11286   u32 cos2_val = 0;
11287
11288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11289     {
11290       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11291         src = 1;
11292       else
11293         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11294         dst = 1;
11295       else if (unformat (input, "proto %U",
11296                          unformat_ethernet_type_host_byte_order, &proto_val))
11297         proto = 1;
11298       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11299         tag1 = 1;
11300       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11301         tag2 = 1;
11302       else if (unformat (input, "ignore-tag1"))
11303         ignore_tag1 = 1;
11304       else if (unformat (input, "ignore-tag2"))
11305         ignore_tag2 = 1;
11306       else if (unformat (input, "cos1 %d", &cos1_val))
11307         cos1 = 1;
11308       else if (unformat (input, "cos2 %d", &cos2_val))
11309         cos2 = 1;
11310       else
11311         break;
11312     }
11313   if ((src + dst + proto + tag1 + tag2 +
11314        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11315     return 0;
11316
11317   if (tag1 || ignore_tag1 || cos1)
11318     len = 18;
11319   if (tag2 || ignore_tag2 || cos2)
11320     len = 22;
11321
11322   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11323
11324   if (dst)
11325     clib_memcpy (match, dst_val, 6);
11326
11327   if (src)
11328     clib_memcpy (match + 6, src_val, 6);
11329
11330   if (tag2)
11331     {
11332       /* inner vlan tag */
11333       match[19] = tag2_val[1];
11334       match[18] = tag2_val[0];
11335       if (cos2)
11336         match[18] |= (cos2_val & 0x7) << 5;
11337       if (proto)
11338         {
11339           match[21] = proto_val & 0xff;
11340           match[20] = proto_val >> 8;
11341         }
11342       if (tag1)
11343         {
11344           match[15] = tag1_val[1];
11345           match[14] = tag1_val[0];
11346         }
11347       if (cos1)
11348         match[14] |= (cos1_val & 0x7) << 5;
11349       *matchp = match;
11350       return 1;
11351     }
11352   if (tag1)
11353     {
11354       match[15] = tag1_val[1];
11355       match[14] = tag1_val[0];
11356       if (proto)
11357         {
11358           match[17] = proto_val & 0xff;
11359           match[16] = proto_val >> 8;
11360         }
11361       if (cos1)
11362         match[14] |= (cos1_val & 0x7) << 5;
11363
11364       *matchp = match;
11365       return 1;
11366     }
11367   if (cos2)
11368     match[18] |= (cos2_val & 0x7) << 5;
11369   if (cos1)
11370     match[14] |= (cos1_val & 0x7) << 5;
11371   if (proto)
11372     {
11373       match[13] = proto_val & 0xff;
11374       match[12] = proto_val >> 8;
11375     }
11376
11377   *matchp = match;
11378   return 1;
11379 }
11380
11381 uword
11382 unformat_qos_source (unformat_input_t * input, va_list * args)
11383 {
11384   int *qs = va_arg (*args, int *);
11385
11386   if (unformat (input, "ip"))
11387     *qs = QOS_SOURCE_IP;
11388   else if (unformat (input, "mpls"))
11389     *qs = QOS_SOURCE_MPLS;
11390   else if (unformat (input, "ext"))
11391     *qs = QOS_SOURCE_EXT;
11392   else if (unformat (input, "vlan"))
11393     *qs = QOS_SOURCE_VLAN;
11394   else
11395     return 0;
11396
11397   return 1;
11398 }
11399 #endif
11400
11401 uword
11402 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11403 {
11404   u8 **matchp = va_arg (*args, u8 **);
11405   u32 skip_n_vectors = va_arg (*args, u32);
11406   u32 match_n_vectors = va_arg (*args, u32);
11407
11408   u8 *match = 0;
11409   u8 *l2 = 0;
11410   u8 *l3 = 0;
11411   u8 *l4 = 0;
11412
11413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11414     {
11415       if (unformat (input, "hex %U", unformat_hex_string, &match))
11416         ;
11417       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11418         ;
11419       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11420         ;
11421       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11422         ;
11423       else
11424         break;
11425     }
11426
11427   if (l4 && !l3)
11428     {
11429       vec_free (match);
11430       vec_free (l2);
11431       vec_free (l4);
11432       return 0;
11433     }
11434
11435   if (match || l2 || l3 || l4)
11436     {
11437       if (l2 || l3 || l4)
11438         {
11439           /* "Win a free Ethernet header in every packet" */
11440           if (l2 == 0)
11441             vec_validate_aligned (l2, 13, sizeof (u32x4));
11442           match = l2;
11443           if (vec_len (l3))
11444             {
11445               vec_append_aligned (match, l3, sizeof (u32x4));
11446               vec_free (l3);
11447             }
11448           if (vec_len (l4))
11449             {
11450               vec_append_aligned (match, l4, sizeof (u32x4));
11451               vec_free (l4);
11452             }
11453         }
11454
11455       /* Make sure the vector is big enough even if key is all 0's */
11456       vec_validate_aligned
11457         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11458          sizeof (u32x4));
11459
11460       /* Set size, include skipped vectors */
11461       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11462
11463       *matchp = match;
11464
11465       return 1;
11466     }
11467
11468   return 0;
11469 }
11470
11471 static int
11472 api_classify_add_del_session (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_classify_add_del_session_t *mp;
11476   int is_add = 1;
11477   u32 table_index = ~0;
11478   u32 hit_next_index = ~0;
11479   u32 opaque_index = ~0;
11480   u8 *match = 0;
11481   i32 advance = 0;
11482   u32 skip_n_vectors = 0;
11483   u32 match_n_vectors = 0;
11484   u32 action = 0;
11485   u32 metadata = 0;
11486   int ret;
11487
11488   /*
11489    * Warning: you have to supply skip_n and match_n
11490    * because the API client cant simply look at the classify
11491    * table object.
11492    */
11493
11494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (i, "del"))
11497         is_add = 0;
11498       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11499                          &hit_next_index))
11500         ;
11501       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11502                          &hit_next_index))
11503         ;
11504       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11505                          &hit_next_index))
11506         ;
11507       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11508         ;
11509       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11510         ;
11511       else if (unformat (i, "opaque-index %d", &opaque_index))
11512         ;
11513       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11514         ;
11515       else if (unformat (i, "match_n %d", &match_n_vectors))
11516         ;
11517       else if (unformat (i, "match %U", api_unformat_classify_match,
11518                          &match, skip_n_vectors, match_n_vectors))
11519         ;
11520       else if (unformat (i, "advance %d", &advance))
11521         ;
11522       else if (unformat (i, "table-index %d", &table_index))
11523         ;
11524       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11525         action = 1;
11526       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11527         action = 2;
11528       else if (unformat (i, "action %d", &action))
11529         ;
11530       else if (unformat (i, "metadata %d", &metadata))
11531         ;
11532       else
11533         break;
11534     }
11535
11536   if (table_index == ~0)
11537     {
11538       errmsg ("Table index required");
11539       return -99;
11540     }
11541
11542   if (is_add && match == 0)
11543     {
11544       errmsg ("Match value required");
11545       return -99;
11546     }
11547
11548   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11549
11550   mp->is_add = is_add;
11551   mp->table_index = ntohl (table_index);
11552   mp->hit_next_index = ntohl (hit_next_index);
11553   mp->opaque_index = ntohl (opaque_index);
11554   mp->advance = ntohl (advance);
11555   mp->action = action;
11556   mp->metadata = ntohl (metadata);
11557   mp->match_len = ntohl (vec_len (match));
11558   clib_memcpy (mp->match, match, vec_len (match));
11559   vec_free (match);
11560
11561   S (mp);
11562   W (ret);
11563   return ret;
11564 }
11565
11566 static int
11567 api_classify_set_interface_ip_table (vat_main_t * vam)
11568 {
11569   unformat_input_t *i = vam->input;
11570   vl_api_classify_set_interface_ip_table_t *mp;
11571   u32 sw_if_index;
11572   int sw_if_index_set;
11573   u32 table_index = ~0;
11574   u8 is_ipv6 = 0;
11575   int ret;
11576
11577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11580         sw_if_index_set = 1;
11581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11582         sw_if_index_set = 1;
11583       else if (unformat (i, "table %d", &table_index))
11584         ;
11585       else
11586         {
11587           clib_warning ("parse error '%U'", format_unformat_error, i);
11588           return -99;
11589         }
11590     }
11591
11592   if (sw_if_index_set == 0)
11593     {
11594       errmsg ("missing interface name or sw_if_index");
11595       return -99;
11596     }
11597
11598
11599   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11600
11601   mp->sw_if_index = ntohl (sw_if_index);
11602   mp->table_index = ntohl (table_index);
11603   mp->is_ipv6 = is_ipv6;
11604
11605   S (mp);
11606   W (ret);
11607   return ret;
11608 }
11609
11610 static int
11611 api_classify_set_interface_l2_tables (vat_main_t * vam)
11612 {
11613   unformat_input_t *i = vam->input;
11614   vl_api_classify_set_interface_l2_tables_t *mp;
11615   u32 sw_if_index;
11616   int sw_if_index_set;
11617   u32 ip4_table_index = ~0;
11618   u32 ip6_table_index = ~0;
11619   u32 other_table_index = ~0;
11620   u32 is_input = 1;
11621   int ret;
11622
11623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11624     {
11625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11626         sw_if_index_set = 1;
11627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11628         sw_if_index_set = 1;
11629       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11630         ;
11631       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11632         ;
11633       else if (unformat (i, "other-table %d", &other_table_index))
11634         ;
11635       else if (unformat (i, "is-input %d", &is_input))
11636         ;
11637       else
11638         {
11639           clib_warning ("parse error '%U'", format_unformat_error, i);
11640           return -99;
11641         }
11642     }
11643
11644   if (sw_if_index_set == 0)
11645     {
11646       errmsg ("missing interface name or sw_if_index");
11647       return -99;
11648     }
11649
11650
11651   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11652
11653   mp->sw_if_index = ntohl (sw_if_index);
11654   mp->ip4_table_index = ntohl (ip4_table_index);
11655   mp->ip6_table_index = ntohl (ip6_table_index);
11656   mp->other_table_index = ntohl (other_table_index);
11657   mp->is_input = (u8) is_input;
11658
11659   S (mp);
11660   W (ret);
11661   return ret;
11662 }
11663
11664 static int
11665 api_set_ipfix_exporter (vat_main_t * vam)
11666 {
11667   unformat_input_t *i = vam->input;
11668   vl_api_set_ipfix_exporter_t *mp;
11669   ip4_address_t collector_address;
11670   u8 collector_address_set = 0;
11671   u32 collector_port = ~0;
11672   ip4_address_t src_address;
11673   u8 src_address_set = 0;
11674   u32 vrf_id = ~0;
11675   u32 path_mtu = ~0;
11676   u32 template_interval = ~0;
11677   u8 udp_checksum = 0;
11678   int ret;
11679
11680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11681     {
11682       if (unformat (i, "collector_address %U", unformat_ip4_address,
11683                     &collector_address))
11684         collector_address_set = 1;
11685       else if (unformat (i, "collector_port %d", &collector_port))
11686         ;
11687       else if (unformat (i, "src_address %U", unformat_ip4_address,
11688                          &src_address))
11689         src_address_set = 1;
11690       else if (unformat (i, "vrf_id %d", &vrf_id))
11691         ;
11692       else if (unformat (i, "path_mtu %d", &path_mtu))
11693         ;
11694       else if (unformat (i, "template_interval %d", &template_interval))
11695         ;
11696       else if (unformat (i, "udp_checksum"))
11697         udp_checksum = 1;
11698       else
11699         break;
11700     }
11701
11702   if (collector_address_set == 0)
11703     {
11704       errmsg ("collector_address required");
11705       return -99;
11706     }
11707
11708   if (src_address_set == 0)
11709     {
11710       errmsg ("src_address required");
11711       return -99;
11712     }
11713
11714   M (SET_IPFIX_EXPORTER, mp);
11715
11716   memcpy (mp->collector_address, collector_address.data,
11717           sizeof (collector_address.data));
11718   mp->collector_port = htons ((u16) collector_port);
11719   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11720   mp->vrf_id = htonl (vrf_id);
11721   mp->path_mtu = htonl (path_mtu);
11722   mp->template_interval = htonl (template_interval);
11723   mp->udp_checksum = udp_checksum;
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_set_ipfix_classify_stream (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_set_ipfix_classify_stream_t *mp;
11735   u32 domain_id = 0;
11736   u32 src_port = UDP_DST_PORT_ipfix;
11737   int ret;
11738
11739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11740     {
11741       if (unformat (i, "domain %d", &domain_id))
11742         ;
11743       else if (unformat (i, "src_port %d", &src_port))
11744         ;
11745       else
11746         {
11747           errmsg ("unknown input `%U'", format_unformat_error, i);
11748           return -99;
11749         }
11750     }
11751
11752   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11753
11754   mp->domain_id = htonl (domain_id);
11755   mp->src_port = htons ((u16) src_port);
11756
11757   S (mp);
11758   W (ret);
11759   return ret;
11760 }
11761
11762 static int
11763 api_ipfix_classify_table_add_del (vat_main_t * vam)
11764 {
11765   unformat_input_t *i = vam->input;
11766   vl_api_ipfix_classify_table_add_del_t *mp;
11767   int is_add = -1;
11768   u32 classify_table_index = ~0;
11769   u8 ip_version = 0;
11770   u8 transport_protocol = 255;
11771   int ret;
11772
11773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11774     {
11775       if (unformat (i, "add"))
11776         is_add = 1;
11777       else if (unformat (i, "del"))
11778         is_add = 0;
11779       else if (unformat (i, "table %d", &classify_table_index))
11780         ;
11781       else if (unformat (i, "ip4"))
11782         ip_version = 4;
11783       else if (unformat (i, "ip6"))
11784         ip_version = 6;
11785       else if (unformat (i, "tcp"))
11786         transport_protocol = 6;
11787       else if (unformat (i, "udp"))
11788         transport_protocol = 17;
11789       else
11790         {
11791           errmsg ("unknown input `%U'", format_unformat_error, i);
11792           return -99;
11793         }
11794     }
11795
11796   if (is_add == -1)
11797     {
11798       errmsg ("expecting: add|del");
11799       return -99;
11800     }
11801   if (classify_table_index == ~0)
11802     {
11803       errmsg ("classifier table not specified");
11804       return -99;
11805     }
11806   if (ip_version == 0)
11807     {
11808       errmsg ("IP version not specified");
11809       return -99;
11810     }
11811
11812   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11813
11814   mp->is_add = is_add;
11815   mp->table_id = htonl (classify_table_index);
11816   mp->ip_version = ip_version;
11817   mp->transport_protocol = transport_protocol;
11818
11819   S (mp);
11820   W (ret);
11821   return ret;
11822 }
11823
11824 static int
11825 api_get_node_index (vat_main_t * vam)
11826 {
11827   unformat_input_t *i = vam->input;
11828   vl_api_get_node_index_t *mp;
11829   u8 *name = 0;
11830   int ret;
11831
11832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11833     {
11834       if (unformat (i, "node %s", &name))
11835         ;
11836       else
11837         break;
11838     }
11839   if (name == 0)
11840     {
11841       errmsg ("node name required");
11842       return -99;
11843     }
11844   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11845     {
11846       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11847       return -99;
11848     }
11849
11850   M (GET_NODE_INDEX, mp);
11851   clib_memcpy (mp->node_name, name, vec_len (name));
11852   vec_free (name);
11853
11854   S (mp);
11855   W (ret);
11856   return ret;
11857 }
11858
11859 static int
11860 api_get_next_index (vat_main_t * vam)
11861 {
11862   unformat_input_t *i = vam->input;
11863   vl_api_get_next_index_t *mp;
11864   u8 *node_name = 0, *next_node_name = 0;
11865   int ret;
11866
11867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11868     {
11869       if (unformat (i, "node-name %s", &node_name))
11870         ;
11871       else if (unformat (i, "next-node-name %s", &next_node_name))
11872         break;
11873     }
11874
11875   if (node_name == 0)
11876     {
11877       errmsg ("node name required");
11878       return -99;
11879     }
11880   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11881     {
11882       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11883       return -99;
11884     }
11885
11886   if (next_node_name == 0)
11887     {
11888       errmsg ("next node name required");
11889       return -99;
11890     }
11891   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11892     {
11893       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11894       return -99;
11895     }
11896
11897   M (GET_NEXT_INDEX, mp);
11898   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11899   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11900   vec_free (node_name);
11901   vec_free (next_node_name);
11902
11903   S (mp);
11904   W (ret);
11905   return ret;
11906 }
11907
11908 static int
11909 api_add_node_next (vat_main_t * vam)
11910 {
11911   unformat_input_t *i = vam->input;
11912   vl_api_add_node_next_t *mp;
11913   u8 *name = 0;
11914   u8 *next = 0;
11915   int ret;
11916
11917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (i, "node %s", &name))
11920         ;
11921       else if (unformat (i, "next %s", &next))
11922         ;
11923       else
11924         break;
11925     }
11926   if (name == 0)
11927     {
11928       errmsg ("node name required");
11929       return -99;
11930     }
11931   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11932     {
11933       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11934       return -99;
11935     }
11936   if (next == 0)
11937     {
11938       errmsg ("next node required");
11939       return -99;
11940     }
11941   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11942     {
11943       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11944       return -99;
11945     }
11946
11947   M (ADD_NODE_NEXT, mp);
11948   clib_memcpy (mp->node_name, name, vec_len (name));
11949   clib_memcpy (mp->next_name, next, vec_len (next));
11950   vec_free (name);
11951   vec_free (next);
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_l2tpv3_create_tunnel (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   ip6_address_t client_address, our_address;
11963   int client_address_set = 0;
11964   int our_address_set = 0;
11965   u32 local_session_id = 0;
11966   u32 remote_session_id = 0;
11967   u64 local_cookie = 0;
11968   u64 remote_cookie = 0;
11969   u8 l2_sublayer_present = 0;
11970   vl_api_l2tpv3_create_tunnel_t *mp;
11971   int ret;
11972
11973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11974     {
11975       if (unformat (i, "client_address %U", unformat_ip6_address,
11976                     &client_address))
11977         client_address_set = 1;
11978       else if (unformat (i, "our_address %U", unformat_ip6_address,
11979                          &our_address))
11980         our_address_set = 1;
11981       else if (unformat (i, "local_session_id %d", &local_session_id))
11982         ;
11983       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11984         ;
11985       else if (unformat (i, "local_cookie %lld", &local_cookie))
11986         ;
11987       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11988         ;
11989       else if (unformat (i, "l2-sublayer-present"))
11990         l2_sublayer_present = 1;
11991       else
11992         break;
11993     }
11994
11995   if (client_address_set == 0)
11996     {
11997       errmsg ("client_address required");
11998       return -99;
11999     }
12000
12001   if (our_address_set == 0)
12002     {
12003       errmsg ("our_address required");
12004       return -99;
12005     }
12006
12007   M (L2TPV3_CREATE_TUNNEL, mp);
12008
12009   clib_memcpy (mp->client_address, client_address.as_u8,
12010                sizeof (mp->client_address));
12011
12012   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12013
12014   mp->local_session_id = ntohl (local_session_id);
12015   mp->remote_session_id = ntohl (remote_session_id);
12016   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12017   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12018   mp->l2_sublayer_present = l2_sublayer_present;
12019   mp->is_ipv6 = 1;
12020
12021   S (mp);
12022   W (ret);
12023   return ret;
12024 }
12025
12026 static int
12027 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12028 {
12029   unformat_input_t *i = vam->input;
12030   u32 sw_if_index;
12031   u8 sw_if_index_set = 0;
12032   u64 new_local_cookie = 0;
12033   u64 new_remote_cookie = 0;
12034   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12035   int ret;
12036
12037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12038     {
12039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12040         sw_if_index_set = 1;
12041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12042         sw_if_index_set = 1;
12043       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12044         ;
12045       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12046         ;
12047       else
12048         break;
12049     }
12050
12051   if (sw_if_index_set == 0)
12052     {
12053       errmsg ("missing interface name or sw_if_index");
12054       return -99;
12055     }
12056
12057   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12058
12059   mp->sw_if_index = ntohl (sw_if_index);
12060   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12061   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12062
12063   S (mp);
12064   W (ret);
12065   return ret;
12066 }
12067
12068 static int
12069 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12070 {
12071   unformat_input_t *i = vam->input;
12072   vl_api_l2tpv3_interface_enable_disable_t *mp;
12073   u32 sw_if_index;
12074   u8 sw_if_index_set = 0;
12075   u8 enable_disable = 1;
12076   int ret;
12077
12078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12079     {
12080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12081         sw_if_index_set = 1;
12082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "enable"))
12085         enable_disable = 1;
12086       else if (unformat (i, "disable"))
12087         enable_disable = 0;
12088       else
12089         break;
12090     }
12091
12092   if (sw_if_index_set == 0)
12093     {
12094       errmsg ("missing interface name or sw_if_index");
12095       return -99;
12096     }
12097
12098   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12099
12100   mp->sw_if_index = ntohl (sw_if_index);
12101   mp->enable_disable = enable_disable;
12102
12103   S (mp);
12104   W (ret);
12105   return ret;
12106 }
12107
12108 static int
12109 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12110 {
12111   unformat_input_t *i = vam->input;
12112   vl_api_l2tpv3_set_lookup_key_t *mp;
12113   u8 key = ~0;
12114   int ret;
12115
12116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12117     {
12118       if (unformat (i, "lookup_v6_src"))
12119         key = L2T_LOOKUP_SRC_ADDRESS;
12120       else if (unformat (i, "lookup_v6_dst"))
12121         key = L2T_LOOKUP_DST_ADDRESS;
12122       else if (unformat (i, "lookup_session_id"))
12123         key = L2T_LOOKUP_SESSION_ID;
12124       else
12125         break;
12126     }
12127
12128   if (key == (u8) ~ 0)
12129     {
12130       errmsg ("l2tp session lookup key unset");
12131       return -99;
12132     }
12133
12134   M (L2TPV3_SET_LOOKUP_KEY, mp);
12135
12136   mp->key = key;
12137
12138   S (mp);
12139   W (ret);
12140   return ret;
12141 }
12142
12143 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12144   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12145 {
12146   vat_main_t *vam = &vat_main;
12147
12148   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12149          format_ip6_address, mp->our_address,
12150          format_ip6_address, mp->client_address,
12151          clib_net_to_host_u32 (mp->sw_if_index));
12152
12153   print (vam->ofp,
12154          "   local cookies %016llx %016llx remote cookie %016llx",
12155          clib_net_to_host_u64 (mp->local_cookie[0]),
12156          clib_net_to_host_u64 (mp->local_cookie[1]),
12157          clib_net_to_host_u64 (mp->remote_cookie));
12158
12159   print (vam->ofp, "   local session-id %d remote session-id %d",
12160          clib_net_to_host_u32 (mp->local_session_id),
12161          clib_net_to_host_u32 (mp->remote_session_id));
12162
12163   print (vam->ofp, "   l2 specific sublayer %s\n",
12164          mp->l2_sublayer_present ? "preset" : "absent");
12165
12166 }
12167
12168 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12169   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12170 {
12171   vat_main_t *vam = &vat_main;
12172   vat_json_node_t *node = NULL;
12173   struct in6_addr addr;
12174
12175   if (VAT_JSON_ARRAY != vam->json_tree.type)
12176     {
12177       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12178       vat_json_init_array (&vam->json_tree);
12179     }
12180   node = vat_json_array_add (&vam->json_tree);
12181
12182   vat_json_init_object (node);
12183
12184   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12185   vat_json_object_add_ip6 (node, "our_address", addr);
12186   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12187   vat_json_object_add_ip6 (node, "client_address", addr);
12188
12189   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12190   vat_json_init_array (lc);
12191   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12192   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12193   vat_json_object_add_uint (node, "remote_cookie",
12194                             clib_net_to_host_u64 (mp->remote_cookie));
12195
12196   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12197   vat_json_object_add_uint (node, "local_session_id",
12198                             clib_net_to_host_u32 (mp->local_session_id));
12199   vat_json_object_add_uint (node, "remote_session_id",
12200                             clib_net_to_host_u32 (mp->remote_session_id));
12201   vat_json_object_add_string_copy (node, "l2_sublayer",
12202                                    mp->l2_sublayer_present ? (u8 *) "present"
12203                                    : (u8 *) "absent");
12204 }
12205
12206 static int
12207 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12208 {
12209   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12210   vl_api_control_ping_t *mp_ping;
12211   int ret;
12212
12213   /* Get list of l2tpv3-tunnel interfaces */
12214   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12215   S (mp);
12216
12217   /* Use a control ping for synchronization */
12218   MPING (CONTROL_PING, mp_ping);
12219   S (mp_ping);
12220
12221   W (ret);
12222   return ret;
12223 }
12224
12225
12226 static void vl_api_sw_interface_tap_v2_details_t_handler
12227   (vl_api_sw_interface_tap_v2_details_t * mp)
12228 {
12229   vat_main_t *vam = &vat_main;
12230
12231   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12232                     mp->host_ip4_prefix_len);
12233   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12234                     mp->host_ip6_prefix_len);
12235
12236   print (vam->ofp,
12237          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12238          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12239          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12240          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12241          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12242
12243   vec_free (ip4);
12244   vec_free (ip6);
12245 }
12246
12247 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12248   (vl_api_sw_interface_tap_v2_details_t * mp)
12249 {
12250   vat_main_t *vam = &vat_main;
12251   vat_json_node_t *node = NULL;
12252
12253   if (VAT_JSON_ARRAY != vam->json_tree.type)
12254     {
12255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12256       vat_json_init_array (&vam->json_tree);
12257     }
12258   node = vat_json_array_add (&vam->json_tree);
12259
12260   vat_json_init_object (node);
12261   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12262   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12263   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12264   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12265   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12266   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12267   vat_json_object_add_string_copy (node, "host_mac_addr",
12268                                    format (0, "%U", format_ethernet_address,
12269                                            &mp->host_mac_addr));
12270   vat_json_object_add_string_copy (node, "host_namespace",
12271                                    mp->host_namespace);
12272   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12273   vat_json_object_add_string_copy (node, "host_ip4_addr",
12274                                    format (0, "%U/%d", format_ip4_address,
12275                                            mp->host_ip4_addr,
12276                                            mp->host_ip4_prefix_len));
12277   vat_json_object_add_string_copy (node, "host_ip6_addr",
12278                                    format (0, "%U/%d", format_ip6_address,
12279                                            mp->host_ip6_addr,
12280                                            mp->host_ip6_prefix_len));
12281
12282 }
12283
12284 static int
12285 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12286 {
12287   vl_api_sw_interface_tap_v2_dump_t *mp;
12288   vl_api_control_ping_t *mp_ping;
12289   int ret;
12290
12291   print (vam->ofp,
12292          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12293          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12294          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12295          "host_ip6_addr");
12296
12297   /* Get list of tap interfaces */
12298   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12299   S (mp);
12300
12301   /* Use a control ping for synchronization */
12302   MPING (CONTROL_PING, mp_ping);
12303   S (mp_ping);
12304
12305   W (ret);
12306   return ret;
12307 }
12308
12309 static void vl_api_sw_interface_virtio_pci_details_t_handler
12310   (vl_api_sw_interface_virtio_pci_details_t * mp)
12311 {
12312   vat_main_t *vam = &vat_main;
12313
12314   typedef union
12315   {
12316     struct
12317     {
12318       u16 domain;
12319       u8 bus;
12320       u8 slot:5;
12321       u8 function:3;
12322     };
12323     u32 as_u32;
12324   } pci_addr_t;
12325   pci_addr_t addr;
12326   addr.as_u32 = ntohl (mp->pci_addr);
12327   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12328                          addr.slot, addr.function);
12329
12330   print (vam->ofp,
12331          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12332          pci_addr, ntohl (mp->sw_if_index),
12333          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12334          format_ethernet_address, mp->mac_addr,
12335          clib_net_to_host_u64 (mp->features));
12336   vec_free (pci_addr);
12337 }
12338
12339 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12340   (vl_api_sw_interface_virtio_pci_details_t * mp)
12341 {
12342   vat_main_t *vam = &vat_main;
12343   vat_json_node_t *node = NULL;
12344
12345   if (VAT_JSON_ARRAY != vam->json_tree.type)
12346     {
12347       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12348       vat_json_init_array (&vam->json_tree);
12349     }
12350   node = vat_json_array_add (&vam->json_tree);
12351
12352   vat_json_init_object (node);
12353   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12354   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12355   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12356   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12357   vat_json_object_add_uint (node, "features",
12358                             clib_net_to_host_u64 (mp->features));
12359   vat_json_object_add_string_copy (node, "mac_addr",
12360                                    format (0, "%U", format_ethernet_address,
12361                                            &mp->mac_addr));
12362 }
12363
12364 static int
12365 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12366 {
12367   vl_api_sw_interface_virtio_pci_dump_t *mp;
12368   vl_api_control_ping_t *mp_ping;
12369   int ret;
12370
12371   print (vam->ofp,
12372          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12373          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12374          "mac_addr", "features");
12375
12376   /* Get list of tap interfaces */
12377   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12378   S (mp);
12379
12380   /* Use a control ping for synchronization */
12381   MPING (CONTROL_PING, mp_ping);
12382   S (mp_ping);
12383
12384   W (ret);
12385   return ret;
12386 }
12387
12388 static int
12389 api_vxlan_offload_rx (vat_main_t * vam)
12390 {
12391   unformat_input_t *line_input = vam->input;
12392   vl_api_vxlan_offload_rx_t *mp;
12393   u32 hw_if_index = ~0, rx_if_index = ~0;
12394   u8 is_add = 1;
12395   int ret;
12396
12397   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12398     {
12399       if (unformat (line_input, "del"))
12400         is_add = 0;
12401       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12402                          &hw_if_index))
12403         ;
12404       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12405         ;
12406       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12407                          &rx_if_index))
12408         ;
12409       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12410         ;
12411       else
12412         {
12413           errmsg ("parse error '%U'", format_unformat_error, line_input);
12414           return -99;
12415         }
12416     }
12417
12418   if (hw_if_index == ~0)
12419     {
12420       errmsg ("no hw interface");
12421       return -99;
12422     }
12423
12424   if (rx_if_index == ~0)
12425     {
12426       errmsg ("no rx tunnel");
12427       return -99;
12428     }
12429
12430   M (VXLAN_OFFLOAD_RX, mp);
12431
12432   mp->hw_if_index = ntohl (hw_if_index);
12433   mp->sw_if_index = ntohl (rx_if_index);
12434   mp->enable = is_add;
12435
12436   S (mp);
12437   W (ret);
12438   return ret;
12439 }
12440
12441 static uword unformat_vxlan_decap_next
12442   (unformat_input_t * input, va_list * args)
12443 {
12444   u32 *result = va_arg (*args, u32 *);
12445   u32 tmp;
12446
12447   if (unformat (input, "l2"))
12448     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12449   else if (unformat (input, "%d", &tmp))
12450     *result = tmp;
12451   else
12452     return 0;
12453   return 1;
12454 }
12455
12456 static int
12457 api_vxlan_add_del_tunnel (vat_main_t * vam)
12458 {
12459   unformat_input_t *line_input = vam->input;
12460   vl_api_vxlan_add_del_tunnel_t *mp;
12461   ip46_address_t src, dst;
12462   u8 is_add = 1;
12463   u8 ipv4_set = 0, ipv6_set = 0;
12464   u8 src_set = 0;
12465   u8 dst_set = 0;
12466   u8 grp_set = 0;
12467   u32 instance = ~0;
12468   u32 mcast_sw_if_index = ~0;
12469   u32 encap_vrf_id = 0;
12470   u32 decap_next_index = ~0;
12471   u32 vni = 0;
12472   int ret;
12473
12474   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12475   clib_memset (&src, 0, sizeof src);
12476   clib_memset (&dst, 0, sizeof dst);
12477
12478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12479     {
12480       if (unformat (line_input, "del"))
12481         is_add = 0;
12482       else if (unformat (line_input, "instance %d", &instance))
12483         ;
12484       else
12485         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12486         {
12487           ipv4_set = 1;
12488           src_set = 1;
12489         }
12490       else
12491         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12492         {
12493           ipv4_set = 1;
12494           dst_set = 1;
12495         }
12496       else
12497         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12498         {
12499           ipv6_set = 1;
12500           src_set = 1;
12501         }
12502       else
12503         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12504         {
12505           ipv6_set = 1;
12506           dst_set = 1;
12507         }
12508       else if (unformat (line_input, "group %U %U",
12509                          unformat_ip4_address, &dst.ip4,
12510                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12511         {
12512           grp_set = dst_set = 1;
12513           ipv4_set = 1;
12514         }
12515       else if (unformat (line_input, "group %U",
12516                          unformat_ip4_address, &dst.ip4))
12517         {
12518           grp_set = dst_set = 1;
12519           ipv4_set = 1;
12520         }
12521       else if (unformat (line_input, "group %U %U",
12522                          unformat_ip6_address, &dst.ip6,
12523                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12524         {
12525           grp_set = dst_set = 1;
12526           ipv6_set = 1;
12527         }
12528       else if (unformat (line_input, "group %U",
12529                          unformat_ip6_address, &dst.ip6))
12530         {
12531           grp_set = dst_set = 1;
12532           ipv6_set = 1;
12533         }
12534       else
12535         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12536         ;
12537       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12538         ;
12539       else if (unformat (line_input, "decap-next %U",
12540                          unformat_vxlan_decap_next, &decap_next_index))
12541         ;
12542       else if (unformat (line_input, "vni %d", &vni))
12543         ;
12544       else
12545         {
12546           errmsg ("parse error '%U'", format_unformat_error, line_input);
12547           return -99;
12548         }
12549     }
12550
12551   if (src_set == 0)
12552     {
12553       errmsg ("tunnel src address not specified");
12554       return -99;
12555     }
12556   if (dst_set == 0)
12557     {
12558       errmsg ("tunnel dst address not specified");
12559       return -99;
12560     }
12561
12562   if (grp_set && !ip46_address_is_multicast (&dst))
12563     {
12564       errmsg ("tunnel group address not multicast");
12565       return -99;
12566     }
12567   if (grp_set && mcast_sw_if_index == ~0)
12568     {
12569       errmsg ("tunnel nonexistent multicast device");
12570       return -99;
12571     }
12572   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12573     {
12574       errmsg ("tunnel dst address must be unicast");
12575       return -99;
12576     }
12577
12578
12579   if (ipv4_set && ipv6_set)
12580     {
12581       errmsg ("both IPv4 and IPv6 addresses specified");
12582       return -99;
12583     }
12584
12585   if ((vni == 0) || (vni >> 24))
12586     {
12587       errmsg ("vni not specified or out of range");
12588       return -99;
12589     }
12590
12591   M (VXLAN_ADD_DEL_TUNNEL, mp);
12592
12593   if (ipv6_set)
12594     {
12595       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12596       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12597     }
12598   else
12599     {
12600       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12601       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12602     }
12603
12604   mp->instance = htonl (instance);
12605   mp->encap_vrf_id = ntohl (encap_vrf_id);
12606   mp->decap_next_index = ntohl (decap_next_index);
12607   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12608   mp->vni = ntohl (vni);
12609   mp->is_add = is_add;
12610   mp->is_ipv6 = ipv6_set;
12611
12612   S (mp);
12613   W (ret);
12614   return ret;
12615 }
12616
12617 static void vl_api_vxlan_tunnel_details_t_handler
12618   (vl_api_vxlan_tunnel_details_t * mp)
12619 {
12620   vat_main_t *vam = &vat_main;
12621   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12622   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12623
12624   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12625          ntohl (mp->sw_if_index),
12626          ntohl (mp->instance),
12627          format_ip46_address, &src, IP46_TYPE_ANY,
12628          format_ip46_address, &dst, IP46_TYPE_ANY,
12629          ntohl (mp->encap_vrf_id),
12630          ntohl (mp->decap_next_index), ntohl (mp->vni),
12631          ntohl (mp->mcast_sw_if_index));
12632 }
12633
12634 static void vl_api_vxlan_tunnel_details_t_handler_json
12635   (vl_api_vxlan_tunnel_details_t * mp)
12636 {
12637   vat_main_t *vam = &vat_main;
12638   vat_json_node_t *node = NULL;
12639
12640   if (VAT_JSON_ARRAY != vam->json_tree.type)
12641     {
12642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12643       vat_json_init_array (&vam->json_tree);
12644     }
12645   node = vat_json_array_add (&vam->json_tree);
12646
12647   vat_json_init_object (node);
12648   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12649
12650   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12651
12652   if (mp->is_ipv6)
12653     {
12654       struct in6_addr ip6;
12655
12656       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12657       vat_json_object_add_ip6 (node, "src_address", ip6);
12658       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12659       vat_json_object_add_ip6 (node, "dst_address", ip6);
12660     }
12661   else
12662     {
12663       struct in_addr ip4;
12664
12665       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12666       vat_json_object_add_ip4 (node, "src_address", ip4);
12667       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12668       vat_json_object_add_ip4 (node, "dst_address", ip4);
12669     }
12670   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12671   vat_json_object_add_uint (node, "decap_next_index",
12672                             ntohl (mp->decap_next_index));
12673   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12674   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12675   vat_json_object_add_uint (node, "mcast_sw_if_index",
12676                             ntohl (mp->mcast_sw_if_index));
12677 }
12678
12679 static int
12680 api_vxlan_tunnel_dump (vat_main_t * vam)
12681 {
12682   unformat_input_t *i = vam->input;
12683   vl_api_vxlan_tunnel_dump_t *mp;
12684   vl_api_control_ping_t *mp_ping;
12685   u32 sw_if_index;
12686   u8 sw_if_index_set = 0;
12687   int ret;
12688
12689   /* Parse args required to build the message */
12690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12691     {
12692       if (unformat (i, "sw_if_index %d", &sw_if_index))
12693         sw_if_index_set = 1;
12694       else
12695         break;
12696     }
12697
12698   if (sw_if_index_set == 0)
12699     {
12700       sw_if_index = ~0;
12701     }
12702
12703   if (!vam->json_output)
12704     {
12705       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12706              "sw_if_index", "instance", "src_address", "dst_address",
12707              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12708     }
12709
12710   /* Get list of vxlan-tunnel interfaces */
12711   M (VXLAN_TUNNEL_DUMP, mp);
12712
12713   mp->sw_if_index = htonl (sw_if_index);
12714
12715   S (mp);
12716
12717   /* Use a control ping for synchronization */
12718   MPING (CONTROL_PING, mp_ping);
12719   S (mp_ping);
12720
12721   W (ret);
12722   return ret;
12723 }
12724
12725 static uword unformat_geneve_decap_next
12726   (unformat_input_t * input, va_list * args)
12727 {
12728   u32 *result = va_arg (*args, u32 *);
12729   u32 tmp;
12730
12731   if (unformat (input, "l2"))
12732     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12733   else if (unformat (input, "%d", &tmp))
12734     *result = tmp;
12735   else
12736     return 0;
12737   return 1;
12738 }
12739
12740 static int
12741 api_geneve_add_del_tunnel (vat_main_t * vam)
12742 {
12743   unformat_input_t *line_input = vam->input;
12744   vl_api_geneve_add_del_tunnel_t *mp;
12745   ip46_address_t src, dst;
12746   u8 is_add = 1;
12747   u8 ipv4_set = 0, ipv6_set = 0;
12748   u8 src_set = 0;
12749   u8 dst_set = 0;
12750   u8 grp_set = 0;
12751   u32 mcast_sw_if_index = ~0;
12752   u32 encap_vrf_id = 0;
12753   u32 decap_next_index = ~0;
12754   u32 vni = 0;
12755   int ret;
12756
12757   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12758   clib_memset (&src, 0, sizeof src);
12759   clib_memset (&dst, 0, sizeof dst);
12760
12761   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12762     {
12763       if (unformat (line_input, "del"))
12764         is_add = 0;
12765       else
12766         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12767         {
12768           ipv4_set = 1;
12769           src_set = 1;
12770         }
12771       else
12772         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12773         {
12774           ipv4_set = 1;
12775           dst_set = 1;
12776         }
12777       else
12778         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12779         {
12780           ipv6_set = 1;
12781           src_set = 1;
12782         }
12783       else
12784         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12785         {
12786           ipv6_set = 1;
12787           dst_set = 1;
12788         }
12789       else if (unformat (line_input, "group %U %U",
12790                          unformat_ip4_address, &dst.ip4,
12791                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12792         {
12793           grp_set = dst_set = 1;
12794           ipv4_set = 1;
12795         }
12796       else if (unformat (line_input, "group %U",
12797                          unformat_ip4_address, &dst.ip4))
12798         {
12799           grp_set = dst_set = 1;
12800           ipv4_set = 1;
12801         }
12802       else if (unformat (line_input, "group %U %U",
12803                          unformat_ip6_address, &dst.ip6,
12804                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12805         {
12806           grp_set = dst_set = 1;
12807           ipv6_set = 1;
12808         }
12809       else if (unformat (line_input, "group %U",
12810                          unformat_ip6_address, &dst.ip6))
12811         {
12812           grp_set = dst_set = 1;
12813           ipv6_set = 1;
12814         }
12815       else
12816         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12817         ;
12818       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12819         ;
12820       else if (unformat (line_input, "decap-next %U",
12821                          unformat_geneve_decap_next, &decap_next_index))
12822         ;
12823       else if (unformat (line_input, "vni %d", &vni))
12824         ;
12825       else
12826         {
12827           errmsg ("parse error '%U'", format_unformat_error, line_input);
12828           return -99;
12829         }
12830     }
12831
12832   if (src_set == 0)
12833     {
12834       errmsg ("tunnel src address not specified");
12835       return -99;
12836     }
12837   if (dst_set == 0)
12838     {
12839       errmsg ("tunnel dst address not specified");
12840       return -99;
12841     }
12842
12843   if (grp_set && !ip46_address_is_multicast (&dst))
12844     {
12845       errmsg ("tunnel group address not multicast");
12846       return -99;
12847     }
12848   if (grp_set && mcast_sw_if_index == ~0)
12849     {
12850       errmsg ("tunnel nonexistent multicast device");
12851       return -99;
12852     }
12853   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12854     {
12855       errmsg ("tunnel dst address must be unicast");
12856       return -99;
12857     }
12858
12859
12860   if (ipv4_set && ipv6_set)
12861     {
12862       errmsg ("both IPv4 and IPv6 addresses specified");
12863       return -99;
12864     }
12865
12866   if ((vni == 0) || (vni >> 24))
12867     {
12868       errmsg ("vni not specified or out of range");
12869       return -99;
12870     }
12871
12872   M (GENEVE_ADD_DEL_TUNNEL, mp);
12873
12874   if (ipv6_set)
12875     {
12876       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12877       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12878     }
12879   else
12880     {
12881       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12882       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12883     }
12884   mp->encap_vrf_id = ntohl (encap_vrf_id);
12885   mp->decap_next_index = ntohl (decap_next_index);
12886   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12887   mp->vni = ntohl (vni);
12888   mp->is_add = is_add;
12889   mp->is_ipv6 = ipv6_set;
12890
12891   S (mp);
12892   W (ret);
12893   return ret;
12894 }
12895
12896 static void vl_api_geneve_tunnel_details_t_handler
12897   (vl_api_geneve_tunnel_details_t * mp)
12898 {
12899   vat_main_t *vam = &vat_main;
12900   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12901   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12902
12903   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12904          ntohl (mp->sw_if_index),
12905          format_ip46_address, &src, IP46_TYPE_ANY,
12906          format_ip46_address, &dst, IP46_TYPE_ANY,
12907          ntohl (mp->encap_vrf_id),
12908          ntohl (mp->decap_next_index), ntohl (mp->vni),
12909          ntohl (mp->mcast_sw_if_index));
12910 }
12911
12912 static void vl_api_geneve_tunnel_details_t_handler_json
12913   (vl_api_geneve_tunnel_details_t * mp)
12914 {
12915   vat_main_t *vam = &vat_main;
12916   vat_json_node_t *node = NULL;
12917
12918   if (VAT_JSON_ARRAY != vam->json_tree.type)
12919     {
12920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12921       vat_json_init_array (&vam->json_tree);
12922     }
12923   node = vat_json_array_add (&vam->json_tree);
12924
12925   vat_json_init_object (node);
12926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12927   if (mp->is_ipv6)
12928     {
12929       struct in6_addr ip6;
12930
12931       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12932       vat_json_object_add_ip6 (node, "src_address", ip6);
12933       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12934       vat_json_object_add_ip6 (node, "dst_address", ip6);
12935     }
12936   else
12937     {
12938       struct in_addr ip4;
12939
12940       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12941       vat_json_object_add_ip4 (node, "src_address", ip4);
12942       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12943       vat_json_object_add_ip4 (node, "dst_address", ip4);
12944     }
12945   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12946   vat_json_object_add_uint (node, "decap_next_index",
12947                             ntohl (mp->decap_next_index));
12948   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12949   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12950   vat_json_object_add_uint (node, "mcast_sw_if_index",
12951                             ntohl (mp->mcast_sw_if_index));
12952 }
12953
12954 static int
12955 api_geneve_tunnel_dump (vat_main_t * vam)
12956 {
12957   unformat_input_t *i = vam->input;
12958   vl_api_geneve_tunnel_dump_t *mp;
12959   vl_api_control_ping_t *mp_ping;
12960   u32 sw_if_index;
12961   u8 sw_if_index_set = 0;
12962   int ret;
12963
12964   /* Parse args required to build the message */
12965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12966     {
12967       if (unformat (i, "sw_if_index %d", &sw_if_index))
12968         sw_if_index_set = 1;
12969       else
12970         break;
12971     }
12972
12973   if (sw_if_index_set == 0)
12974     {
12975       sw_if_index = ~0;
12976     }
12977
12978   if (!vam->json_output)
12979     {
12980       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12981              "sw_if_index", "local_address", "remote_address",
12982              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12983     }
12984
12985   /* Get list of geneve-tunnel interfaces */
12986   M (GENEVE_TUNNEL_DUMP, mp);
12987
12988   mp->sw_if_index = htonl (sw_if_index);
12989
12990   S (mp);
12991
12992   /* Use a control ping for synchronization */
12993   M (CONTROL_PING, mp_ping);
12994   S (mp_ping);
12995
12996   W (ret);
12997   return ret;
12998 }
12999
13000 static int
13001 api_gre_tunnel_add_del (vat_main_t * vam)
13002 {
13003   unformat_input_t *line_input = vam->input;
13004   vl_api_address_t src = { }, dst =
13005   {
13006   };
13007   vl_api_gre_tunnel_add_del_t *mp;
13008   vl_api_gre_tunnel_type_t t_type;
13009   u8 is_add = 1;
13010   u8 src_set = 0;
13011   u8 dst_set = 0;
13012   u32 outer_fib_id = 0;
13013   u32 session_id = 0;
13014   u32 instance = ~0;
13015   int ret;
13016
13017   t_type = GRE_API_TUNNEL_TYPE_L3;
13018
13019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13020     {
13021       if (unformat (line_input, "del"))
13022         is_add = 0;
13023       else if (unformat (line_input, "instance %d", &instance))
13024         ;
13025       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13026         {
13027           src_set = 1;
13028         }
13029       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13030         {
13031           dst_set = 1;
13032         }
13033       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13034         ;
13035       else if (unformat (line_input, "teb"))
13036         t_type = GRE_API_TUNNEL_TYPE_TEB;
13037       else if (unformat (line_input, "erspan %d", &session_id))
13038         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13039       else
13040         {
13041           errmsg ("parse error '%U'", format_unformat_error, line_input);
13042           return -99;
13043         }
13044     }
13045
13046   if (src_set == 0)
13047     {
13048       errmsg ("tunnel src address not specified");
13049       return -99;
13050     }
13051   if (dst_set == 0)
13052     {
13053       errmsg ("tunnel dst address not specified");
13054       return -99;
13055     }
13056
13057   M (GRE_TUNNEL_ADD_DEL, mp);
13058
13059   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13060   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13061
13062   mp->tunnel.instance = htonl (instance);
13063   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13064   mp->is_add = is_add;
13065   mp->tunnel.session_id = htons ((u16) session_id);
13066   mp->tunnel.type = htonl (t_type);
13067
13068   S (mp);
13069   W (ret);
13070   return ret;
13071 }
13072
13073 static void vl_api_gre_tunnel_details_t_handler
13074   (vl_api_gre_tunnel_details_t * mp)
13075 {
13076   vat_main_t *vam = &vat_main;
13077
13078   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13079          ntohl (mp->tunnel.sw_if_index),
13080          ntohl (mp->tunnel.instance),
13081          format_vl_api_address, &mp->tunnel.src,
13082          format_vl_api_address, &mp->tunnel.dst,
13083          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13084          ntohl (mp->tunnel.session_id));
13085 }
13086
13087 static void vl_api_gre_tunnel_details_t_handler_json
13088   (vl_api_gre_tunnel_details_t * mp)
13089 {
13090   vat_main_t *vam = &vat_main;
13091   vat_json_node_t *node = NULL;
13092
13093   if (VAT_JSON_ARRAY != vam->json_tree.type)
13094     {
13095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13096       vat_json_init_array (&vam->json_tree);
13097     }
13098   node = vat_json_array_add (&vam->json_tree);
13099
13100   vat_json_init_object (node);
13101   vat_json_object_add_uint (node, "sw_if_index",
13102                             ntohl (mp->tunnel.sw_if_index));
13103   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13104
13105   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13106   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13107   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13108   vat_json_object_add_uint (node, "outer_fib_id",
13109                             ntohl (mp->tunnel.outer_fib_id));
13110   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13111 }
13112
13113 static int
13114 api_gre_tunnel_dump (vat_main_t * vam)
13115 {
13116   unformat_input_t *i = vam->input;
13117   vl_api_gre_tunnel_dump_t *mp;
13118   vl_api_control_ping_t *mp_ping;
13119   u32 sw_if_index;
13120   u8 sw_if_index_set = 0;
13121   int ret;
13122
13123   /* Parse args required to build the message */
13124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13125     {
13126       if (unformat (i, "sw_if_index %d", &sw_if_index))
13127         sw_if_index_set = 1;
13128       else
13129         break;
13130     }
13131
13132   if (sw_if_index_set == 0)
13133     {
13134       sw_if_index = ~0;
13135     }
13136
13137   if (!vam->json_output)
13138     {
13139       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13140              "sw_if_index", "instance", "src_address", "dst_address",
13141              "tunnel_type", "outer_fib_id", "session_id");
13142     }
13143
13144   /* Get list of gre-tunnel interfaces */
13145   M (GRE_TUNNEL_DUMP, mp);
13146
13147   mp->sw_if_index = htonl (sw_if_index);
13148
13149   S (mp);
13150
13151   /* Use a control ping for synchronization */
13152   MPING (CONTROL_PING, mp_ping);
13153   S (mp_ping);
13154
13155   W (ret);
13156   return ret;
13157 }
13158
13159 static int
13160 api_l2_fib_clear_table (vat_main_t * vam)
13161 {
13162 //  unformat_input_t * i = vam->input;
13163   vl_api_l2_fib_clear_table_t *mp;
13164   int ret;
13165
13166   M (L2_FIB_CLEAR_TABLE, mp);
13167
13168   S (mp);
13169   W (ret);
13170   return ret;
13171 }
13172
13173 static int
13174 api_l2_interface_efp_filter (vat_main_t * vam)
13175 {
13176   unformat_input_t *i = vam->input;
13177   vl_api_l2_interface_efp_filter_t *mp;
13178   u32 sw_if_index;
13179   u8 enable = 1;
13180   u8 sw_if_index_set = 0;
13181   int ret;
13182
13183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13184     {
13185       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13186         sw_if_index_set = 1;
13187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13188         sw_if_index_set = 1;
13189       else if (unformat (i, "enable"))
13190         enable = 1;
13191       else if (unformat (i, "disable"))
13192         enable = 0;
13193       else
13194         {
13195           clib_warning ("parse error '%U'", format_unformat_error, i);
13196           return -99;
13197         }
13198     }
13199
13200   if (sw_if_index_set == 0)
13201     {
13202       errmsg ("missing sw_if_index");
13203       return -99;
13204     }
13205
13206   M (L2_INTERFACE_EFP_FILTER, mp);
13207
13208   mp->sw_if_index = ntohl (sw_if_index);
13209   mp->enable_disable = enable;
13210
13211   S (mp);
13212   W (ret);
13213   return ret;
13214 }
13215
13216 #define foreach_vtr_op                          \
13217 _("disable",  L2_VTR_DISABLED)                  \
13218 _("push-1",  L2_VTR_PUSH_1)                     \
13219 _("push-2",  L2_VTR_PUSH_2)                     \
13220 _("pop-1",  L2_VTR_POP_1)                       \
13221 _("pop-2",  L2_VTR_POP_2)                       \
13222 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13223 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13224 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13225 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13226
13227 static int
13228 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13229 {
13230   unformat_input_t *i = vam->input;
13231   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13232   u32 sw_if_index;
13233   u8 sw_if_index_set = 0;
13234   u8 vtr_op_set = 0;
13235   u32 vtr_op = 0;
13236   u32 push_dot1q = 1;
13237   u32 tag1 = ~0;
13238   u32 tag2 = ~0;
13239   int ret;
13240
13241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13244         sw_if_index_set = 1;
13245       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13246         sw_if_index_set = 1;
13247       else if (unformat (i, "vtr_op %d", &vtr_op))
13248         vtr_op_set = 1;
13249 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13250       foreach_vtr_op
13251 #undef _
13252         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13253         ;
13254       else if (unformat (i, "tag1 %d", &tag1))
13255         ;
13256       else if (unformat (i, "tag2 %d", &tag2))
13257         ;
13258       else
13259         {
13260           clib_warning ("parse error '%U'", format_unformat_error, i);
13261           return -99;
13262         }
13263     }
13264
13265   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13266     {
13267       errmsg ("missing vtr operation or sw_if_index");
13268       return -99;
13269     }
13270
13271   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13272   mp->sw_if_index = ntohl (sw_if_index);
13273   mp->vtr_op = ntohl (vtr_op);
13274   mp->push_dot1q = ntohl (push_dot1q);
13275   mp->tag1 = ntohl (tag1);
13276   mp->tag2 = ntohl (tag2);
13277
13278   S (mp);
13279   W (ret);
13280   return ret;
13281 }
13282
13283 static int
13284 api_create_vhost_user_if (vat_main_t * vam)
13285 {
13286   unformat_input_t *i = vam->input;
13287   vl_api_create_vhost_user_if_t *mp;
13288   u8 *file_name;
13289   u8 is_server = 0;
13290   u8 file_name_set = 0;
13291   u32 custom_dev_instance = ~0;
13292   u8 hwaddr[6];
13293   u8 use_custom_mac = 0;
13294   u8 disable_mrg_rxbuf = 0;
13295   u8 disable_indirect_desc = 0;
13296   u8 *tag = 0;
13297   int ret;
13298
13299   /* Shut up coverity */
13300   clib_memset (hwaddr, 0, sizeof (hwaddr));
13301
13302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13303     {
13304       if (unformat (i, "socket %s", &file_name))
13305         {
13306           file_name_set = 1;
13307         }
13308       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13309         ;
13310       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13311         use_custom_mac = 1;
13312       else if (unformat (i, "server"))
13313         is_server = 1;
13314       else if (unformat (i, "disable_mrg_rxbuf"))
13315         disable_mrg_rxbuf = 1;
13316       else if (unformat (i, "disable_indirect_desc"))
13317         disable_indirect_desc = 1;
13318       else if (unformat (i, "tag %s", &tag))
13319         ;
13320       else
13321         break;
13322     }
13323
13324   if (file_name_set == 0)
13325     {
13326       errmsg ("missing socket file name");
13327       return -99;
13328     }
13329
13330   if (vec_len (file_name) > 255)
13331     {
13332       errmsg ("socket file name too long");
13333       return -99;
13334     }
13335   vec_add1 (file_name, 0);
13336
13337   M (CREATE_VHOST_USER_IF, mp);
13338
13339   mp->is_server = is_server;
13340   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13341   mp->disable_indirect_desc = disable_indirect_desc;
13342   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13343   vec_free (file_name);
13344   if (custom_dev_instance != ~0)
13345     {
13346       mp->renumber = 1;
13347       mp->custom_dev_instance = ntohl (custom_dev_instance);
13348     }
13349
13350   mp->use_custom_mac = use_custom_mac;
13351   clib_memcpy (mp->mac_address, hwaddr, 6);
13352   if (tag)
13353     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13354   vec_free (tag);
13355
13356   S (mp);
13357   W (ret);
13358   return ret;
13359 }
13360
13361 static int
13362 api_modify_vhost_user_if (vat_main_t * vam)
13363 {
13364   unformat_input_t *i = vam->input;
13365   vl_api_modify_vhost_user_if_t *mp;
13366   u8 *file_name;
13367   u8 is_server = 0;
13368   u8 file_name_set = 0;
13369   u32 custom_dev_instance = ~0;
13370   u8 sw_if_index_set = 0;
13371   u32 sw_if_index = (u32) ~ 0;
13372   int ret;
13373
13374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13375     {
13376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13377         sw_if_index_set = 1;
13378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13379         sw_if_index_set = 1;
13380       else if (unformat (i, "socket %s", &file_name))
13381         {
13382           file_name_set = 1;
13383         }
13384       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13385         ;
13386       else if (unformat (i, "server"))
13387         is_server = 1;
13388       else
13389         break;
13390     }
13391
13392   if (sw_if_index_set == 0)
13393     {
13394       errmsg ("missing sw_if_index or interface name");
13395       return -99;
13396     }
13397
13398   if (file_name_set == 0)
13399     {
13400       errmsg ("missing socket file name");
13401       return -99;
13402     }
13403
13404   if (vec_len (file_name) > 255)
13405     {
13406       errmsg ("socket file name too long");
13407       return -99;
13408     }
13409   vec_add1 (file_name, 0);
13410
13411   M (MODIFY_VHOST_USER_IF, mp);
13412
13413   mp->sw_if_index = ntohl (sw_if_index);
13414   mp->is_server = is_server;
13415   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13416   vec_free (file_name);
13417   if (custom_dev_instance != ~0)
13418     {
13419       mp->renumber = 1;
13420       mp->custom_dev_instance = ntohl (custom_dev_instance);
13421     }
13422
13423   S (mp);
13424   W (ret);
13425   return ret;
13426 }
13427
13428 static int
13429 api_delete_vhost_user_if (vat_main_t * vam)
13430 {
13431   unformat_input_t *i = vam->input;
13432   vl_api_delete_vhost_user_if_t *mp;
13433   u32 sw_if_index = ~0;
13434   u8 sw_if_index_set = 0;
13435   int ret;
13436
13437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13438     {
13439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13440         sw_if_index_set = 1;
13441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13442         sw_if_index_set = 1;
13443       else
13444         break;
13445     }
13446
13447   if (sw_if_index_set == 0)
13448     {
13449       errmsg ("missing sw_if_index or interface name");
13450       return -99;
13451     }
13452
13453
13454   M (DELETE_VHOST_USER_IF, mp);
13455
13456   mp->sw_if_index = ntohl (sw_if_index);
13457
13458   S (mp);
13459   W (ret);
13460   return ret;
13461 }
13462
13463 static void vl_api_sw_interface_vhost_user_details_t_handler
13464   (vl_api_sw_interface_vhost_user_details_t * mp)
13465 {
13466   vat_main_t *vam = &vat_main;
13467
13468   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13469          (char *) mp->interface_name,
13470          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13471          clib_net_to_host_u64 (mp->features), mp->is_server,
13472          ntohl (mp->num_regions), (char *) mp->sock_filename);
13473   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13474 }
13475
13476 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13477   (vl_api_sw_interface_vhost_user_details_t * mp)
13478 {
13479   vat_main_t *vam = &vat_main;
13480   vat_json_node_t *node = NULL;
13481
13482   if (VAT_JSON_ARRAY != vam->json_tree.type)
13483     {
13484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13485       vat_json_init_array (&vam->json_tree);
13486     }
13487   node = vat_json_array_add (&vam->json_tree);
13488
13489   vat_json_init_object (node);
13490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13491   vat_json_object_add_string_copy (node, "interface_name",
13492                                    mp->interface_name);
13493   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13494                             ntohl (mp->virtio_net_hdr_sz));
13495   vat_json_object_add_uint (node, "features",
13496                             clib_net_to_host_u64 (mp->features));
13497   vat_json_object_add_uint (node, "is_server", mp->is_server);
13498   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13499   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13500   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13501 }
13502
13503 static int
13504 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13505 {
13506   vl_api_sw_interface_vhost_user_dump_t *mp;
13507   vl_api_control_ping_t *mp_ping;
13508   int ret;
13509   print (vam->ofp,
13510          "Interface name            idx hdr_sz features server regions filename");
13511
13512   /* Get list of vhost-user interfaces */
13513   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13514   S (mp);
13515
13516   /* Use a control ping for synchronization */
13517   MPING (CONTROL_PING, mp_ping);
13518   S (mp_ping);
13519
13520   W (ret);
13521   return ret;
13522 }
13523
13524 static int
13525 api_show_version (vat_main_t * vam)
13526 {
13527   vl_api_show_version_t *mp;
13528   int ret;
13529
13530   M (SHOW_VERSION, mp);
13531
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537
13538 static int
13539 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13540 {
13541   unformat_input_t *line_input = vam->input;
13542   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13543   ip4_address_t local4, remote4;
13544   ip6_address_t local6, remote6;
13545   u8 is_add = 1;
13546   u8 ipv4_set = 0, ipv6_set = 0;
13547   u8 local_set = 0;
13548   u8 remote_set = 0;
13549   u8 grp_set = 0;
13550   u32 mcast_sw_if_index = ~0;
13551   u32 encap_vrf_id = 0;
13552   u32 decap_vrf_id = 0;
13553   u8 protocol = ~0;
13554   u32 vni;
13555   u8 vni_set = 0;
13556   int ret;
13557
13558   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13559   clib_memset (&local4, 0, sizeof local4);
13560   clib_memset (&remote4, 0, sizeof remote4);
13561   clib_memset (&local6, 0, sizeof local6);
13562   clib_memset (&remote6, 0, sizeof remote6);
13563
13564   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13565     {
13566       if (unformat (line_input, "del"))
13567         is_add = 0;
13568       else if (unformat (line_input, "local %U",
13569                          unformat_ip4_address, &local4))
13570         {
13571           local_set = 1;
13572           ipv4_set = 1;
13573         }
13574       else if (unformat (line_input, "remote %U",
13575                          unformat_ip4_address, &remote4))
13576         {
13577           remote_set = 1;
13578           ipv4_set = 1;
13579         }
13580       else if (unformat (line_input, "local %U",
13581                          unformat_ip6_address, &local6))
13582         {
13583           local_set = 1;
13584           ipv6_set = 1;
13585         }
13586       else if (unformat (line_input, "remote %U",
13587                          unformat_ip6_address, &remote6))
13588         {
13589           remote_set = 1;
13590           ipv6_set = 1;
13591         }
13592       else if (unformat (line_input, "group %U %U",
13593                          unformat_ip4_address, &remote4,
13594                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13595         {
13596           grp_set = remote_set = 1;
13597           ipv4_set = 1;
13598         }
13599       else if (unformat (line_input, "group %U",
13600                          unformat_ip4_address, &remote4))
13601         {
13602           grp_set = remote_set = 1;
13603           ipv4_set = 1;
13604         }
13605       else if (unformat (line_input, "group %U %U",
13606                          unformat_ip6_address, &remote6,
13607                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13608         {
13609           grp_set = remote_set = 1;
13610           ipv6_set = 1;
13611         }
13612       else if (unformat (line_input, "group %U",
13613                          unformat_ip6_address, &remote6))
13614         {
13615           grp_set = remote_set = 1;
13616           ipv6_set = 1;
13617         }
13618       else
13619         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13620         ;
13621       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13622         ;
13623       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13624         ;
13625       else if (unformat (line_input, "vni %d", &vni))
13626         vni_set = 1;
13627       else if (unformat (line_input, "next-ip4"))
13628         protocol = 1;
13629       else if (unformat (line_input, "next-ip6"))
13630         protocol = 2;
13631       else if (unformat (line_input, "next-ethernet"))
13632         protocol = 3;
13633       else if (unformat (line_input, "next-nsh"))
13634         protocol = 4;
13635       else
13636         {
13637           errmsg ("parse error '%U'", format_unformat_error, line_input);
13638           return -99;
13639         }
13640     }
13641
13642   if (local_set == 0)
13643     {
13644       errmsg ("tunnel local address not specified");
13645       return -99;
13646     }
13647   if (remote_set == 0)
13648     {
13649       errmsg ("tunnel remote address not specified");
13650       return -99;
13651     }
13652   if (grp_set && mcast_sw_if_index == ~0)
13653     {
13654       errmsg ("tunnel nonexistent multicast device");
13655       return -99;
13656     }
13657   if (ipv4_set && ipv6_set)
13658     {
13659       errmsg ("both IPv4 and IPv6 addresses specified");
13660       return -99;
13661     }
13662
13663   if (vni_set == 0)
13664     {
13665       errmsg ("vni not specified");
13666       return -99;
13667     }
13668
13669   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13670
13671
13672   if (ipv6_set)
13673     {
13674       clib_memcpy (&mp->local, &local6, sizeof (local6));
13675       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13676     }
13677   else
13678     {
13679       clib_memcpy (&mp->local, &local4, sizeof (local4));
13680       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13681     }
13682
13683   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13684   mp->encap_vrf_id = ntohl (encap_vrf_id);
13685   mp->decap_vrf_id = ntohl (decap_vrf_id);
13686   mp->protocol = protocol;
13687   mp->vni = ntohl (vni);
13688   mp->is_add = is_add;
13689   mp->is_ipv6 = ipv6_set;
13690
13691   S (mp);
13692   W (ret);
13693   return ret;
13694 }
13695
13696 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13697   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13698 {
13699   vat_main_t *vam = &vat_main;
13700   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13701   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13702
13703   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13704          ntohl (mp->sw_if_index),
13705          format_ip46_address, &local, IP46_TYPE_ANY,
13706          format_ip46_address, &remote, IP46_TYPE_ANY,
13707          ntohl (mp->vni), mp->protocol,
13708          ntohl (mp->mcast_sw_if_index),
13709          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13710 }
13711
13712
13713 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13714   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13715 {
13716   vat_main_t *vam = &vat_main;
13717   vat_json_node_t *node = NULL;
13718   struct in_addr ip4;
13719   struct in6_addr ip6;
13720
13721   if (VAT_JSON_ARRAY != vam->json_tree.type)
13722     {
13723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13724       vat_json_init_array (&vam->json_tree);
13725     }
13726   node = vat_json_array_add (&vam->json_tree);
13727
13728   vat_json_init_object (node);
13729   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13730   if (mp->is_ipv6)
13731     {
13732       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13733       vat_json_object_add_ip6 (node, "local", ip6);
13734       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13735       vat_json_object_add_ip6 (node, "remote", ip6);
13736     }
13737   else
13738     {
13739       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13740       vat_json_object_add_ip4 (node, "local", ip4);
13741       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13742       vat_json_object_add_ip4 (node, "remote", ip4);
13743     }
13744   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13745   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13746   vat_json_object_add_uint (node, "mcast_sw_if_index",
13747                             ntohl (mp->mcast_sw_if_index));
13748   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13749   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13750   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13751 }
13752
13753 static int
13754 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13755 {
13756   unformat_input_t *i = vam->input;
13757   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13758   vl_api_control_ping_t *mp_ping;
13759   u32 sw_if_index;
13760   u8 sw_if_index_set = 0;
13761   int ret;
13762
13763   /* Parse args required to build the message */
13764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13765     {
13766       if (unformat (i, "sw_if_index %d", &sw_if_index))
13767         sw_if_index_set = 1;
13768       else
13769         break;
13770     }
13771
13772   if (sw_if_index_set == 0)
13773     {
13774       sw_if_index = ~0;
13775     }
13776
13777   if (!vam->json_output)
13778     {
13779       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13780              "sw_if_index", "local", "remote", "vni",
13781              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13782     }
13783
13784   /* Get list of vxlan-tunnel interfaces */
13785   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13786
13787   mp->sw_if_index = htonl (sw_if_index);
13788
13789   S (mp);
13790
13791   /* Use a control ping for synchronization */
13792   MPING (CONTROL_PING, mp_ping);
13793   S (mp_ping);
13794
13795   W (ret);
13796   return ret;
13797 }
13798
13799 static void vl_api_l2_fib_table_details_t_handler
13800   (vl_api_l2_fib_table_details_t * mp)
13801 {
13802   vat_main_t *vam = &vat_main;
13803
13804   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13805          "       %d       %d     %d",
13806          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13807          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13808          mp->bvi_mac);
13809 }
13810
13811 static void vl_api_l2_fib_table_details_t_handler_json
13812   (vl_api_l2_fib_table_details_t * mp)
13813 {
13814   vat_main_t *vam = &vat_main;
13815   vat_json_node_t *node = NULL;
13816
13817   if (VAT_JSON_ARRAY != vam->json_tree.type)
13818     {
13819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13820       vat_json_init_array (&vam->json_tree);
13821     }
13822   node = vat_json_array_add (&vam->json_tree);
13823
13824   vat_json_init_object (node);
13825   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13826   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13827   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13828   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13829   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13830   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13831 }
13832
13833 static int
13834 api_l2_fib_table_dump (vat_main_t * vam)
13835 {
13836   unformat_input_t *i = vam->input;
13837   vl_api_l2_fib_table_dump_t *mp;
13838   vl_api_control_ping_t *mp_ping;
13839   u32 bd_id;
13840   u8 bd_id_set = 0;
13841   int ret;
13842
13843   /* Parse args required to build the message */
13844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (i, "bd_id %d", &bd_id))
13847         bd_id_set = 1;
13848       else
13849         break;
13850     }
13851
13852   if (bd_id_set == 0)
13853     {
13854       errmsg ("missing bridge domain");
13855       return -99;
13856     }
13857
13858   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13859
13860   /* Get list of l2 fib entries */
13861   M (L2_FIB_TABLE_DUMP, mp);
13862
13863   mp->bd_id = ntohl (bd_id);
13864   S (mp);
13865
13866   /* Use a control ping for synchronization */
13867   MPING (CONTROL_PING, mp_ping);
13868   S (mp_ping);
13869
13870   W (ret);
13871   return ret;
13872 }
13873
13874
13875 static int
13876 api_interface_name_renumber (vat_main_t * vam)
13877 {
13878   unformat_input_t *line_input = vam->input;
13879   vl_api_interface_name_renumber_t *mp;
13880   u32 sw_if_index = ~0;
13881   u32 new_show_dev_instance = ~0;
13882   int ret;
13883
13884   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13887                     &sw_if_index))
13888         ;
13889       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13890         ;
13891       else if (unformat (line_input, "new_show_dev_instance %d",
13892                          &new_show_dev_instance))
13893         ;
13894       else
13895         break;
13896     }
13897
13898   if (sw_if_index == ~0)
13899     {
13900       errmsg ("missing interface name or sw_if_index");
13901       return -99;
13902     }
13903
13904   if (new_show_dev_instance == ~0)
13905     {
13906       errmsg ("missing new_show_dev_instance");
13907       return -99;
13908     }
13909
13910   M (INTERFACE_NAME_RENUMBER, mp);
13911
13912   mp->sw_if_index = ntohl (sw_if_index);
13913   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13914
13915   S (mp);
13916   W (ret);
13917   return ret;
13918 }
13919
13920 static int
13921 api_ip_probe_neighbor (vat_main_t * vam)
13922 {
13923   unformat_input_t *i = vam->input;
13924   vl_api_ip_probe_neighbor_t *mp;
13925   vl_api_address_t dst_adr = { };
13926   u8 int_set = 0;
13927   u8 adr_set = 0;
13928   u32 sw_if_index;
13929   int ret;
13930
13931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13932     {
13933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13934         int_set = 1;
13935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13936         int_set = 1;
13937       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13938         adr_set = 1;
13939       else
13940         break;
13941     }
13942
13943   if (int_set == 0)
13944     {
13945       errmsg ("missing interface");
13946       return -99;
13947     }
13948
13949   if (adr_set == 0)
13950     {
13951       errmsg ("missing addresses");
13952       return -99;
13953     }
13954
13955   M (IP_PROBE_NEIGHBOR, mp);
13956
13957   mp->sw_if_index = ntohl (sw_if_index);
13958   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13959
13960   S (mp);
13961   W (ret);
13962   return ret;
13963 }
13964
13965 static int
13966 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13967 {
13968   unformat_input_t *i = vam->input;
13969   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13970   u8 mode = IP_SCAN_V46_NEIGHBORS;
13971   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13972   int ret;
13973
13974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13975     {
13976       if (unformat (i, "ip4"))
13977         mode = IP_SCAN_V4_NEIGHBORS;
13978       else if (unformat (i, "ip6"))
13979         mode = IP_SCAN_V6_NEIGHBORS;
13980       if (unformat (i, "both"))
13981         mode = IP_SCAN_V46_NEIGHBORS;
13982       else if (unformat (i, "disable"))
13983         mode = IP_SCAN_DISABLED;
13984       else if (unformat (i, "interval %d", &interval))
13985         ;
13986       else if (unformat (i, "max-time %d", &time))
13987         ;
13988       else if (unformat (i, "max-update %d", &update))
13989         ;
13990       else if (unformat (i, "delay %d", &delay))
13991         ;
13992       else if (unformat (i, "stale %d", &stale))
13993         ;
13994       else
13995         break;
13996     }
13997
13998   if (interval > 255)
13999     {
14000       errmsg ("interval cannot exceed 255 minutes.");
14001       return -99;
14002     }
14003   if (time > 255)
14004     {
14005       errmsg ("max-time cannot exceed 255 usec.");
14006       return -99;
14007     }
14008   if (update > 255)
14009     {
14010       errmsg ("max-update cannot exceed 255.");
14011       return -99;
14012     }
14013   if (delay > 255)
14014     {
14015       errmsg ("delay cannot exceed 255 msec.");
14016       return -99;
14017     }
14018   if (stale > 255)
14019     {
14020       errmsg ("stale cannot exceed 255 minutes.");
14021       return -99;
14022     }
14023
14024   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14025   mp->mode = mode;
14026   mp->scan_interval = interval;
14027   mp->max_proc_time = time;
14028   mp->max_update = update;
14029   mp->scan_int_delay = delay;
14030   mp->stale_threshold = stale;
14031
14032   S (mp);
14033   W (ret);
14034   return ret;
14035 }
14036
14037 static int
14038 api_want_ip4_arp_events (vat_main_t * vam)
14039 {
14040   unformat_input_t *line_input = vam->input;
14041   vl_api_want_ip4_arp_events_t *mp;
14042   ip4_address_t address;
14043   int address_set = 0;
14044   u32 enable_disable = 1;
14045   int ret;
14046
14047   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14048     {
14049       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14050         address_set = 1;
14051       else if (unformat (line_input, "del"))
14052         enable_disable = 0;
14053       else
14054         break;
14055     }
14056
14057   if (address_set == 0)
14058     {
14059       errmsg ("missing addresses");
14060       return -99;
14061     }
14062
14063   M (WANT_IP4_ARP_EVENTS, mp);
14064   mp->enable_disable = enable_disable;
14065   mp->pid = htonl (getpid ());
14066   clib_memcpy (mp->ip, &address, sizeof (address));
14067
14068   S (mp);
14069   W (ret);
14070   return ret;
14071 }
14072
14073 static int
14074 api_want_ip6_nd_events (vat_main_t * vam)
14075 {
14076   unformat_input_t *line_input = vam->input;
14077   vl_api_want_ip6_nd_events_t *mp;
14078   vl_api_ip6_address_t address;
14079   int address_set = 0;
14080   u32 enable_disable = 1;
14081   int ret;
14082
14083   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat
14086           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14087         address_set = 1;
14088       else if (unformat (line_input, "del"))
14089         enable_disable = 0;
14090       else
14091         break;
14092     }
14093
14094   if (address_set == 0)
14095     {
14096       errmsg ("missing addresses");
14097       return -99;
14098     }
14099
14100   M (WANT_IP6_ND_EVENTS, mp);
14101   mp->enable_disable = enable_disable;
14102   mp->pid = htonl (getpid ());
14103   clib_memcpy (&mp->ip, &address, sizeof (address));
14104
14105   S (mp);
14106   W (ret);
14107   return ret;
14108 }
14109
14110 static int
14111 api_want_l2_macs_events (vat_main_t * vam)
14112 {
14113   unformat_input_t *line_input = vam->input;
14114   vl_api_want_l2_macs_events_t *mp;
14115   u8 enable_disable = 1;
14116   u32 scan_delay = 0;
14117   u32 max_macs_in_event = 0;
14118   u32 learn_limit = 0;
14119   int ret;
14120
14121   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14122     {
14123       if (unformat (line_input, "learn-limit %d", &learn_limit))
14124         ;
14125       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14126         ;
14127       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14128         ;
14129       else if (unformat (line_input, "disable"))
14130         enable_disable = 0;
14131       else
14132         break;
14133     }
14134
14135   M (WANT_L2_MACS_EVENTS, mp);
14136   mp->enable_disable = enable_disable;
14137   mp->pid = htonl (getpid ());
14138   mp->learn_limit = htonl (learn_limit);
14139   mp->scan_delay = (u8) scan_delay;
14140   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14141   S (mp);
14142   W (ret);
14143   return ret;
14144 }
14145
14146 static int
14147 api_input_acl_set_interface (vat_main_t * vam)
14148 {
14149   unformat_input_t *i = vam->input;
14150   vl_api_input_acl_set_interface_t *mp;
14151   u32 sw_if_index;
14152   int sw_if_index_set;
14153   u32 ip4_table_index = ~0;
14154   u32 ip6_table_index = ~0;
14155   u32 l2_table_index = ~0;
14156   u8 is_add = 1;
14157   int ret;
14158
14159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14160     {
14161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14162         sw_if_index_set = 1;
14163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14164         sw_if_index_set = 1;
14165       else if (unformat (i, "del"))
14166         is_add = 0;
14167       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14168         ;
14169       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14170         ;
14171       else if (unformat (i, "l2-table %d", &l2_table_index))
14172         ;
14173       else
14174         {
14175           clib_warning ("parse error '%U'", format_unformat_error, i);
14176           return -99;
14177         }
14178     }
14179
14180   if (sw_if_index_set == 0)
14181     {
14182       errmsg ("missing interface name or sw_if_index");
14183       return -99;
14184     }
14185
14186   M (INPUT_ACL_SET_INTERFACE, mp);
14187
14188   mp->sw_if_index = ntohl (sw_if_index);
14189   mp->ip4_table_index = ntohl (ip4_table_index);
14190   mp->ip6_table_index = ntohl (ip6_table_index);
14191   mp->l2_table_index = ntohl (l2_table_index);
14192   mp->is_add = is_add;
14193
14194   S (mp);
14195   W (ret);
14196   return ret;
14197 }
14198
14199 static int
14200 api_output_acl_set_interface (vat_main_t * vam)
14201 {
14202   unformat_input_t *i = vam->input;
14203   vl_api_output_acl_set_interface_t *mp;
14204   u32 sw_if_index;
14205   int sw_if_index_set;
14206   u32 ip4_table_index = ~0;
14207   u32 ip6_table_index = ~0;
14208   u32 l2_table_index = ~0;
14209   u8 is_add = 1;
14210   int ret;
14211
14212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14213     {
14214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14215         sw_if_index_set = 1;
14216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14217         sw_if_index_set = 1;
14218       else if (unformat (i, "del"))
14219         is_add = 0;
14220       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14221         ;
14222       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14223         ;
14224       else if (unformat (i, "l2-table %d", &l2_table_index))
14225         ;
14226       else
14227         {
14228           clib_warning ("parse error '%U'", format_unformat_error, i);
14229           return -99;
14230         }
14231     }
14232
14233   if (sw_if_index_set == 0)
14234     {
14235       errmsg ("missing interface name or sw_if_index");
14236       return -99;
14237     }
14238
14239   M (OUTPUT_ACL_SET_INTERFACE, mp);
14240
14241   mp->sw_if_index = ntohl (sw_if_index);
14242   mp->ip4_table_index = ntohl (ip4_table_index);
14243   mp->ip6_table_index = ntohl (ip6_table_index);
14244   mp->l2_table_index = ntohl (l2_table_index);
14245   mp->is_add = is_add;
14246
14247   S (mp);
14248   W (ret);
14249   return ret;
14250 }
14251
14252 static int
14253 api_ip_address_dump (vat_main_t * vam)
14254 {
14255   unformat_input_t *i = vam->input;
14256   vl_api_ip_address_dump_t *mp;
14257   vl_api_control_ping_t *mp_ping;
14258   u32 sw_if_index = ~0;
14259   u8 sw_if_index_set = 0;
14260   u8 ipv4_set = 0;
14261   u8 ipv6_set = 0;
14262   int ret;
14263
14264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14265     {
14266       if (unformat (i, "sw_if_index %d", &sw_if_index))
14267         sw_if_index_set = 1;
14268       else
14269         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14270         sw_if_index_set = 1;
14271       else if (unformat (i, "ipv4"))
14272         ipv4_set = 1;
14273       else if (unformat (i, "ipv6"))
14274         ipv6_set = 1;
14275       else
14276         break;
14277     }
14278
14279   if (ipv4_set && ipv6_set)
14280     {
14281       errmsg ("ipv4 and ipv6 flags cannot be both set");
14282       return -99;
14283     }
14284
14285   if ((!ipv4_set) && (!ipv6_set))
14286     {
14287       errmsg ("no ipv4 nor ipv6 flag set");
14288       return -99;
14289     }
14290
14291   if (sw_if_index_set == 0)
14292     {
14293       errmsg ("missing interface name or sw_if_index");
14294       return -99;
14295     }
14296
14297   vam->current_sw_if_index = sw_if_index;
14298   vam->is_ipv6 = ipv6_set;
14299
14300   M (IP_ADDRESS_DUMP, mp);
14301   mp->sw_if_index = ntohl (sw_if_index);
14302   mp->is_ipv6 = ipv6_set;
14303   S (mp);
14304
14305   /* Use a control ping for synchronization */
14306   MPING (CONTROL_PING, mp_ping);
14307   S (mp_ping);
14308
14309   W (ret);
14310   return ret;
14311 }
14312
14313 static int
14314 api_ip_dump (vat_main_t * vam)
14315 {
14316   vl_api_ip_dump_t *mp;
14317   vl_api_control_ping_t *mp_ping;
14318   unformat_input_t *in = vam->input;
14319   int ipv4_set = 0;
14320   int ipv6_set = 0;
14321   int is_ipv6;
14322   int i;
14323   int ret;
14324
14325   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14326     {
14327       if (unformat (in, "ipv4"))
14328         ipv4_set = 1;
14329       else if (unformat (in, "ipv6"))
14330         ipv6_set = 1;
14331       else
14332         break;
14333     }
14334
14335   if (ipv4_set && ipv6_set)
14336     {
14337       errmsg ("ipv4 and ipv6 flags cannot be both set");
14338       return -99;
14339     }
14340
14341   if ((!ipv4_set) && (!ipv6_set))
14342     {
14343       errmsg ("no ipv4 nor ipv6 flag set");
14344       return -99;
14345     }
14346
14347   is_ipv6 = ipv6_set;
14348   vam->is_ipv6 = is_ipv6;
14349
14350   /* free old data */
14351   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14352     {
14353       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14354     }
14355   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14356
14357   M (IP_DUMP, mp);
14358   mp->is_ipv6 = ipv6_set;
14359   S (mp);
14360
14361   /* Use a control ping for synchronization */
14362   MPING (CONTROL_PING, mp_ping);
14363   S (mp_ping);
14364
14365   W (ret);
14366   return ret;
14367 }
14368
14369 static int
14370 api_ipsec_spd_add_del (vat_main_t * vam)
14371 {
14372   unformat_input_t *i = vam->input;
14373   vl_api_ipsec_spd_add_del_t *mp;
14374   u32 spd_id = ~0;
14375   u8 is_add = 1;
14376   int ret;
14377
14378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14379     {
14380       if (unformat (i, "spd_id %d", &spd_id))
14381         ;
14382       else if (unformat (i, "del"))
14383         is_add = 0;
14384       else
14385         {
14386           clib_warning ("parse error '%U'", format_unformat_error, i);
14387           return -99;
14388         }
14389     }
14390   if (spd_id == ~0)
14391     {
14392       errmsg ("spd_id must be set");
14393       return -99;
14394     }
14395
14396   M (IPSEC_SPD_ADD_DEL, mp);
14397
14398   mp->spd_id = ntohl (spd_id);
14399   mp->is_add = is_add;
14400
14401   S (mp);
14402   W (ret);
14403   return ret;
14404 }
14405
14406 static int
14407 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14408 {
14409   unformat_input_t *i = vam->input;
14410   vl_api_ipsec_interface_add_del_spd_t *mp;
14411   u32 sw_if_index;
14412   u8 sw_if_index_set = 0;
14413   u32 spd_id = (u32) ~ 0;
14414   u8 is_add = 1;
14415   int ret;
14416
14417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14418     {
14419       if (unformat (i, "del"))
14420         is_add = 0;
14421       else if (unformat (i, "spd_id %d", &spd_id))
14422         ;
14423       else
14424         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14425         sw_if_index_set = 1;
14426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14427         sw_if_index_set = 1;
14428       else
14429         {
14430           clib_warning ("parse error '%U'", format_unformat_error, i);
14431           return -99;
14432         }
14433
14434     }
14435
14436   if (spd_id == (u32) ~ 0)
14437     {
14438       errmsg ("spd_id must be set");
14439       return -99;
14440     }
14441
14442   if (sw_if_index_set == 0)
14443     {
14444       errmsg ("missing interface name or sw_if_index");
14445       return -99;
14446     }
14447
14448   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14449
14450   mp->spd_id = ntohl (spd_id);
14451   mp->sw_if_index = ntohl (sw_if_index);
14452   mp->is_add = is_add;
14453
14454   S (mp);
14455   W (ret);
14456   return ret;
14457 }
14458
14459 static int
14460 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14461 {
14462   unformat_input_t *i = vam->input;
14463   vl_api_ipsec_spd_entry_add_del_t *mp;
14464   u8 is_add = 1, is_outbound = 0;
14465   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14466   i32 priority = 0;
14467   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14468   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14469   vl_api_address_t laddr_start = { }, laddr_stop =
14470   {
14471   }, raddr_start =
14472   {
14473   }, raddr_stop =
14474   {
14475   };
14476   int ret;
14477
14478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14479     {
14480       if (unformat (i, "del"))
14481         is_add = 0;
14482       if (unformat (i, "outbound"))
14483         is_outbound = 1;
14484       if (unformat (i, "inbound"))
14485         is_outbound = 0;
14486       else if (unformat (i, "spd_id %d", &spd_id))
14487         ;
14488       else if (unformat (i, "sa_id %d", &sa_id))
14489         ;
14490       else if (unformat (i, "priority %d", &priority))
14491         ;
14492       else if (unformat (i, "protocol %d", &protocol))
14493         ;
14494       else if (unformat (i, "lport_start %d", &lport_start))
14495         ;
14496       else if (unformat (i, "lport_stop %d", &lport_stop))
14497         ;
14498       else if (unformat (i, "rport_start %d", &rport_start))
14499         ;
14500       else if (unformat (i, "rport_stop %d", &rport_stop))
14501         ;
14502       else if (unformat (i, "laddr_start %U",
14503                          unformat_vl_api_address, &laddr_start))
14504         ;
14505       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14506                          &laddr_stop))
14507         ;
14508       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14509                          &raddr_start))
14510         ;
14511       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14512                          &raddr_stop))
14513         ;
14514       else
14515         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14516         {
14517           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14518             {
14519               clib_warning ("unsupported action: 'resolve'");
14520               return -99;
14521             }
14522         }
14523       else
14524         {
14525           clib_warning ("parse error '%U'", format_unformat_error, i);
14526           return -99;
14527         }
14528
14529     }
14530
14531   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14532
14533   mp->is_add = is_add;
14534
14535   mp->entry.spd_id = ntohl (spd_id);
14536   mp->entry.priority = ntohl (priority);
14537   mp->entry.is_outbound = is_outbound;
14538
14539   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14540                sizeof (vl_api_address_t));
14541   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14542                sizeof (vl_api_address_t));
14543   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14544                sizeof (vl_api_address_t));
14545   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14546                sizeof (vl_api_address_t));
14547
14548   mp->entry.protocol = (u8) protocol;
14549   mp->entry.local_port_start = ntohs ((u16) lport_start);
14550   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14551   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14552   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14553   mp->entry.policy = (u8) policy;
14554   mp->entry.sa_id = ntohl (sa_id);
14555
14556   S (mp);
14557   W (ret);
14558   return ret;
14559 }
14560
14561 static int
14562 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14563 {
14564   unformat_input_t *i = vam->input;
14565   vl_api_ipsec_sad_entry_add_del_t *mp;
14566   u32 sad_id = 0, spi = 0;
14567   u8 *ck = 0, *ik = 0;
14568   u8 is_add = 1;
14569
14570   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14571   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14572   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14573   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14574   vl_api_address_t tun_src, tun_dst;
14575   int ret;
14576
14577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14578     {
14579       if (unformat (i, "del"))
14580         is_add = 0;
14581       else if (unformat (i, "sad_id %d", &sad_id))
14582         ;
14583       else if (unformat (i, "spi %d", &spi))
14584         ;
14585       else if (unformat (i, "esp"))
14586         protocol = IPSEC_API_PROTO_ESP;
14587       else
14588         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14589         {
14590           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14591           if (ADDRESS_IP6 == tun_src.af)
14592             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14593         }
14594       else
14595         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14596         {
14597           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14598           if (ADDRESS_IP6 == tun_src.af)
14599             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14600         }
14601       else
14602         if (unformat (i, "crypto_alg %U",
14603                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14604         ;
14605       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14606         ;
14607       else if (unformat (i, "integ_alg %U",
14608                          unformat_ipsec_api_integ_alg, &integ_alg))
14609         ;
14610       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14611         ;
14612       else
14613         {
14614           clib_warning ("parse error '%U'", format_unformat_error, i);
14615           return -99;
14616         }
14617
14618     }
14619
14620   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14621
14622   mp->is_add = is_add;
14623   mp->entry.sad_id = ntohl (sad_id);
14624   mp->entry.protocol = protocol;
14625   mp->entry.spi = ntohl (spi);
14626   mp->entry.flags = flags;
14627
14628   mp->entry.crypto_algorithm = crypto_alg;
14629   mp->entry.integrity_algorithm = integ_alg;
14630   mp->entry.crypto_key.length = vec_len (ck);
14631   mp->entry.integrity_key.length = vec_len (ik);
14632
14633   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14634     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14635
14636   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14637     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14638
14639   if (ck)
14640     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14641   if (ik)
14642     clib_memcpy (mp->entry.integrity_key.data, ik,
14643                  mp->entry.integrity_key.length);
14644
14645   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14646     {
14647       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14648                    sizeof (mp->entry.tunnel_src));
14649       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14650                    sizeof (mp->entry.tunnel_dst));
14651     }
14652
14653   S (mp);
14654   W (ret);
14655   return ret;
14656 }
14657
14658 static int
14659 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14660 {
14661   unformat_input_t *i = vam->input;
14662   vl_api_ipsec_tunnel_if_add_del_t *mp;
14663   u32 local_spi = 0, remote_spi = 0;
14664   u32 crypto_alg = 0, integ_alg = 0;
14665   u8 *lck = NULL, *rck = NULL;
14666   u8 *lik = NULL, *rik = NULL;
14667   vl_api_address_t local_ip = { 0 };
14668   vl_api_address_t remote_ip = { 0 };
14669   f64 before = 0;
14670   u8 is_add = 1;
14671   u8 esn = 0;
14672   u8 anti_replay = 0;
14673   u8 renumber = 0;
14674   u32 instance = ~0;
14675   u32 count = 1, jj;
14676   int ret = -1;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "del"))
14681         is_add = 0;
14682       else if (unformat (i, "esn"))
14683         esn = 1;
14684       else if (unformat (i, "anti-replay"))
14685         anti_replay = 1;
14686       else if (unformat (i, "count %d", &count))
14687         ;
14688       else if (unformat (i, "local_spi %d", &local_spi))
14689         ;
14690       else if (unformat (i, "remote_spi %d", &remote_spi))
14691         ;
14692       else
14693         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14694         ;
14695       else
14696         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14697         ;
14698       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14699         ;
14700       else
14701         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14702         ;
14703       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14704         ;
14705       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14706         ;
14707       else
14708         if (unformat
14709             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14710         {
14711           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14712             {
14713               errmsg ("unsupported crypto-alg: '%U'\n",
14714                       format_ipsec_crypto_alg, crypto_alg);
14715               return -99;
14716             }
14717         }
14718       else
14719         if (unformat
14720             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14721         {
14722           if (integ_alg >= IPSEC_INTEG_N_ALG)
14723             {
14724               errmsg ("unsupported integ-alg: '%U'\n",
14725                       format_ipsec_integ_alg, integ_alg);
14726               return -99;
14727             }
14728         }
14729       else if (unformat (i, "instance %u", &instance))
14730         renumber = 1;
14731       else
14732         {
14733           errmsg ("parse error '%U'\n", format_unformat_error, i);
14734           return -99;
14735         }
14736     }
14737
14738   if (count > 1)
14739     {
14740       /* Turn on async mode */
14741       vam->async_mode = 1;
14742       vam->async_errors = 0;
14743       before = vat_time_now (vam);
14744     }
14745
14746   for (jj = 0; jj < count; jj++)
14747     {
14748       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14749
14750       mp->is_add = is_add;
14751       mp->esn = esn;
14752       mp->anti_replay = anti_replay;
14753
14754       if (jj > 0)
14755         increment_address (&remote_ip);
14756
14757       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14758       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14759
14760       mp->local_spi = htonl (local_spi + jj);
14761       mp->remote_spi = htonl (remote_spi + jj);
14762       mp->crypto_alg = (u8) crypto_alg;
14763
14764       mp->local_crypto_key_len = 0;
14765       if (lck)
14766         {
14767           mp->local_crypto_key_len = vec_len (lck);
14768           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14769             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14770           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14771         }
14772
14773       mp->remote_crypto_key_len = 0;
14774       if (rck)
14775         {
14776           mp->remote_crypto_key_len = vec_len (rck);
14777           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14778             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14779           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14780         }
14781
14782       mp->integ_alg = (u8) integ_alg;
14783
14784       mp->local_integ_key_len = 0;
14785       if (lik)
14786         {
14787           mp->local_integ_key_len = vec_len (lik);
14788           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14789             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14790           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14791         }
14792
14793       mp->remote_integ_key_len = 0;
14794       if (rik)
14795         {
14796           mp->remote_integ_key_len = vec_len (rik);
14797           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14798             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14799           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14800         }
14801
14802       if (renumber)
14803         {
14804           mp->renumber = renumber;
14805           mp->show_instance = ntohl (instance);
14806         }
14807       S (mp);
14808     }
14809
14810   /* When testing multiple add/del ops, use a control-ping to sync */
14811   if (count > 1)
14812     {
14813       vl_api_control_ping_t *mp_ping;
14814       f64 after;
14815       f64 timeout;
14816
14817       /* Shut off async mode */
14818       vam->async_mode = 0;
14819
14820       MPING (CONTROL_PING, mp_ping);
14821       S (mp_ping);
14822
14823       timeout = vat_time_now (vam) + 1.0;
14824       while (vat_time_now (vam) < timeout)
14825         if (vam->result_ready == 1)
14826           goto out;
14827       vam->retval = -99;
14828
14829     out:
14830       if (vam->retval == -99)
14831         errmsg ("timeout");
14832
14833       if (vam->async_errors > 0)
14834         {
14835           errmsg ("%d asynchronous errors", vam->async_errors);
14836           vam->retval = -98;
14837         }
14838       vam->async_errors = 0;
14839       after = vat_time_now (vam);
14840
14841       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14842       if (jj > 0)
14843         count = jj;
14844
14845       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14846              count, after - before, count / (after - before));
14847     }
14848   else
14849     {
14850       /* Wait for a reply... */
14851       W (ret);
14852       return ret;
14853     }
14854
14855   return ret;
14856 }
14857
14858 static void
14859 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14860 {
14861   vat_main_t *vam = &vat_main;
14862
14863   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14864          "crypto_key %U integ_alg %u integ_key %U flags %x "
14865          "tunnel_src_addr %U tunnel_dst_addr %U "
14866          "salt %u seq_outbound %lu last_seq_inbound %lu "
14867          "replay_window %lu\n",
14868          ntohl (mp->entry.sad_id),
14869          ntohl (mp->sw_if_index),
14870          ntohl (mp->entry.spi),
14871          ntohl (mp->entry.protocol),
14872          ntohl (mp->entry.crypto_algorithm),
14873          format_hex_bytes, mp->entry.crypto_key.data,
14874          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14875          format_hex_bytes, mp->entry.integrity_key.data,
14876          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14877          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14878          &mp->entry.tunnel_dst, ntohl (mp->salt),
14879          clib_net_to_host_u64 (mp->seq_outbound),
14880          clib_net_to_host_u64 (mp->last_seq_inbound),
14881          clib_net_to_host_u64 (mp->replay_window));
14882 }
14883
14884 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14885 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14886
14887 static void vl_api_ipsec_sa_details_t_handler_json
14888   (vl_api_ipsec_sa_details_t * mp)
14889 {
14890   vat_main_t *vam = &vat_main;
14891   vat_json_node_t *node = NULL;
14892   vl_api_ipsec_sad_flags_t flags;
14893
14894   if (VAT_JSON_ARRAY != vam->json_tree.type)
14895     {
14896       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14897       vat_json_init_array (&vam->json_tree);
14898     }
14899   node = vat_json_array_add (&vam->json_tree);
14900
14901   vat_json_init_object (node);
14902   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14903   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14904   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14905   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14906   vat_json_object_add_uint (node, "crypto_alg",
14907                             ntohl (mp->entry.crypto_algorithm));
14908   vat_json_object_add_uint (node, "integ_alg",
14909                             ntohl (mp->entry.integrity_algorithm));
14910   flags = ntohl (mp->entry.flags);
14911   vat_json_object_add_uint (node, "use_esn",
14912                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14913   vat_json_object_add_uint (node, "use_anti_replay",
14914                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14915   vat_json_object_add_uint (node, "is_tunnel",
14916                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14917   vat_json_object_add_uint (node, "is_tunnel_ip6",
14918                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14919   vat_json_object_add_uint (node, "udp_encap",
14920                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14921   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14922                              mp->entry.crypto_key.length);
14923   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14924                              mp->entry.integrity_key.length);
14925   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14926   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14927   vat_json_object_add_uint (node, "replay_window",
14928                             clib_net_to_host_u64 (mp->replay_window));
14929 }
14930
14931 static int
14932 api_ipsec_sa_dump (vat_main_t * vam)
14933 {
14934   unformat_input_t *i = vam->input;
14935   vl_api_ipsec_sa_dump_t *mp;
14936   vl_api_control_ping_t *mp_ping;
14937   u32 sa_id = ~0;
14938   int ret;
14939
14940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14941     {
14942       if (unformat (i, "sa_id %d", &sa_id))
14943         ;
14944       else
14945         {
14946           clib_warning ("parse error '%U'", format_unformat_error, i);
14947           return -99;
14948         }
14949     }
14950
14951   M (IPSEC_SA_DUMP, mp);
14952
14953   mp->sa_id = ntohl (sa_id);
14954
14955   S (mp);
14956
14957   /* Use a control ping for synchronization */
14958   M (CONTROL_PING, mp_ping);
14959   S (mp_ping);
14960
14961   W (ret);
14962   return ret;
14963 }
14964
14965 static int
14966 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14967 {
14968   unformat_input_t *i = vam->input;
14969   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14970   u32 sw_if_index = ~0;
14971   u32 sa_id = ~0;
14972   u8 is_outbound = (u8) ~ 0;
14973   int ret;
14974
14975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14978         ;
14979       else if (unformat (i, "sa_id %d", &sa_id))
14980         ;
14981       else if (unformat (i, "outbound"))
14982         is_outbound = 1;
14983       else if (unformat (i, "inbound"))
14984         is_outbound = 0;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990     }
14991
14992   if (sw_if_index == ~0)
14993     {
14994       errmsg ("interface must be specified");
14995       return -99;
14996     }
14997
14998   if (sa_id == ~0)
14999     {
15000       errmsg ("SA ID must be specified");
15001       return -99;
15002     }
15003
15004   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15005
15006   mp->sw_if_index = htonl (sw_if_index);
15007   mp->sa_id = htonl (sa_id);
15008   mp->is_outbound = is_outbound;
15009
15010   S (mp);
15011   W (ret);
15012
15013   return ret;
15014 }
15015
15016 static int
15017 api_get_first_msg_id (vat_main_t * vam)
15018 {
15019   vl_api_get_first_msg_id_t *mp;
15020   unformat_input_t *i = vam->input;
15021   u8 *name;
15022   u8 name_set = 0;
15023   int ret;
15024
15025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15026     {
15027       if (unformat (i, "client %s", &name))
15028         name_set = 1;
15029       else
15030         break;
15031     }
15032
15033   if (name_set == 0)
15034     {
15035       errmsg ("missing client name");
15036       return -99;
15037     }
15038   vec_add1 (name, 0);
15039
15040   if (vec_len (name) > 63)
15041     {
15042       errmsg ("client name too long");
15043       return -99;
15044     }
15045
15046   M (GET_FIRST_MSG_ID, mp);
15047   clib_memcpy (mp->name, name, vec_len (name));
15048   S (mp);
15049   W (ret);
15050   return ret;
15051 }
15052
15053 static int
15054 api_cop_interface_enable_disable (vat_main_t * vam)
15055 {
15056   unformat_input_t *line_input = vam->input;
15057   vl_api_cop_interface_enable_disable_t *mp;
15058   u32 sw_if_index = ~0;
15059   u8 enable_disable = 1;
15060   int ret;
15061
15062   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15063     {
15064       if (unformat (line_input, "disable"))
15065         enable_disable = 0;
15066       if (unformat (line_input, "enable"))
15067         enable_disable = 1;
15068       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15069                          vam, &sw_if_index))
15070         ;
15071       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15072         ;
15073       else
15074         break;
15075     }
15076
15077   if (sw_if_index == ~0)
15078     {
15079       errmsg ("missing interface name or sw_if_index");
15080       return -99;
15081     }
15082
15083   /* Construct the API message */
15084   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15085   mp->sw_if_index = ntohl (sw_if_index);
15086   mp->enable_disable = enable_disable;
15087
15088   /* send it... */
15089   S (mp);
15090   /* Wait for the reply */
15091   W (ret);
15092   return ret;
15093 }
15094
15095 static int
15096 api_cop_whitelist_enable_disable (vat_main_t * vam)
15097 {
15098   unformat_input_t *line_input = vam->input;
15099   vl_api_cop_whitelist_enable_disable_t *mp;
15100   u32 sw_if_index = ~0;
15101   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15102   u32 fib_id = 0;
15103   int ret;
15104
15105   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15106     {
15107       if (unformat (line_input, "ip4"))
15108         ip4 = 1;
15109       else if (unformat (line_input, "ip6"))
15110         ip6 = 1;
15111       else if (unformat (line_input, "default"))
15112         default_cop = 1;
15113       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15114                          vam, &sw_if_index))
15115         ;
15116       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15117         ;
15118       else if (unformat (line_input, "fib-id %d", &fib_id))
15119         ;
15120       else
15121         break;
15122     }
15123
15124   if (sw_if_index == ~0)
15125     {
15126       errmsg ("missing interface name or sw_if_index");
15127       return -99;
15128     }
15129
15130   /* Construct the API message */
15131   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15132   mp->sw_if_index = ntohl (sw_if_index);
15133   mp->fib_id = ntohl (fib_id);
15134   mp->ip4 = ip4;
15135   mp->ip6 = ip6;
15136   mp->default_cop = default_cop;
15137
15138   /* send it... */
15139   S (mp);
15140   /* Wait for the reply */
15141   W (ret);
15142   return ret;
15143 }
15144
15145 static int
15146 api_get_node_graph (vat_main_t * vam)
15147 {
15148   vl_api_get_node_graph_t *mp;
15149   int ret;
15150
15151   M (GET_NODE_GRAPH, mp);
15152
15153   /* send it... */
15154   S (mp);
15155   /* Wait for the reply */
15156   W (ret);
15157   return ret;
15158 }
15159
15160 /* *INDENT-OFF* */
15161 /** Used for parsing LISP eids */
15162 typedef CLIB_PACKED(struct{
15163   u8 addr[16];   /**< eid address */
15164   u32 len;       /**< prefix length if IP */
15165   u8 type;      /**< type of eid */
15166 }) lisp_eid_vat_t;
15167 /* *INDENT-ON* */
15168
15169 static uword
15170 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15171 {
15172   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15173
15174   clib_memset (a, 0, sizeof (a[0]));
15175
15176   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15177     {
15178       a->type = 0;              /* ipv4 type */
15179     }
15180   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15181     {
15182       a->type = 1;              /* ipv6 type */
15183     }
15184   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15185     {
15186       a->type = 2;              /* mac type */
15187     }
15188   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15189     {
15190       a->type = 3;              /* NSH type */
15191       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15192       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15193     }
15194   else
15195     {
15196       return 0;
15197     }
15198
15199   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15200     {
15201       return 0;
15202     }
15203
15204   return 1;
15205 }
15206
15207 static int
15208 lisp_eid_size_vat (u8 type)
15209 {
15210   switch (type)
15211     {
15212     case 0:
15213       return 4;
15214     case 1:
15215       return 16;
15216     case 2:
15217       return 6;
15218     case 3:
15219       return 5;
15220     }
15221   return 0;
15222 }
15223
15224 static void
15225 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15226 {
15227   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15228 }
15229
15230 static int
15231 api_one_add_del_locator_set (vat_main_t * vam)
15232 {
15233   unformat_input_t *input = vam->input;
15234   vl_api_one_add_del_locator_set_t *mp;
15235   u8 is_add = 1;
15236   u8 *locator_set_name = NULL;
15237   u8 locator_set_name_set = 0;
15238   vl_api_local_locator_t locator, *locators = 0;
15239   u32 sw_if_index, priority, weight;
15240   u32 data_len = 0;
15241
15242   int ret;
15243   /* Parse args required to build the message */
15244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15245     {
15246       if (unformat (input, "del"))
15247         {
15248           is_add = 0;
15249         }
15250       else if (unformat (input, "locator-set %s", &locator_set_name))
15251         {
15252           locator_set_name_set = 1;
15253         }
15254       else if (unformat (input, "sw_if_index %u p %u w %u",
15255                          &sw_if_index, &priority, &weight))
15256         {
15257           locator.sw_if_index = htonl (sw_if_index);
15258           locator.priority = priority;
15259           locator.weight = weight;
15260           vec_add1 (locators, locator);
15261         }
15262       else
15263         if (unformat
15264             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15265              &sw_if_index, &priority, &weight))
15266         {
15267           locator.sw_if_index = htonl (sw_if_index);
15268           locator.priority = priority;
15269           locator.weight = weight;
15270           vec_add1 (locators, locator);
15271         }
15272       else
15273         break;
15274     }
15275
15276   if (locator_set_name_set == 0)
15277     {
15278       errmsg ("missing locator-set name");
15279       vec_free (locators);
15280       return -99;
15281     }
15282
15283   if (vec_len (locator_set_name) > 64)
15284     {
15285       errmsg ("locator-set name too long");
15286       vec_free (locator_set_name);
15287       vec_free (locators);
15288       return -99;
15289     }
15290   vec_add1 (locator_set_name, 0);
15291
15292   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15293
15294   /* Construct the API message */
15295   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15296
15297   mp->is_add = is_add;
15298   clib_memcpy (mp->locator_set_name, locator_set_name,
15299                vec_len (locator_set_name));
15300   vec_free (locator_set_name);
15301
15302   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15303   if (locators)
15304     clib_memcpy (mp->locators, locators, data_len);
15305   vec_free (locators);
15306
15307   /* send it... */
15308   S (mp);
15309
15310   /* Wait for a reply... */
15311   W (ret);
15312   return ret;
15313 }
15314
15315 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15316
15317 static int
15318 api_one_add_del_locator (vat_main_t * vam)
15319 {
15320   unformat_input_t *input = vam->input;
15321   vl_api_one_add_del_locator_t *mp;
15322   u32 tmp_if_index = ~0;
15323   u32 sw_if_index = ~0;
15324   u8 sw_if_index_set = 0;
15325   u8 sw_if_index_if_name_set = 0;
15326   u32 priority = ~0;
15327   u8 priority_set = 0;
15328   u32 weight = ~0;
15329   u8 weight_set = 0;
15330   u8 is_add = 1;
15331   u8 *locator_set_name = NULL;
15332   u8 locator_set_name_set = 0;
15333   int ret;
15334
15335   /* Parse args required to build the message */
15336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15337     {
15338       if (unformat (input, "del"))
15339         {
15340           is_add = 0;
15341         }
15342       else if (unformat (input, "locator-set %s", &locator_set_name))
15343         {
15344           locator_set_name_set = 1;
15345         }
15346       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15347                          &tmp_if_index))
15348         {
15349           sw_if_index_if_name_set = 1;
15350           sw_if_index = tmp_if_index;
15351         }
15352       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15353         {
15354           sw_if_index_set = 1;
15355           sw_if_index = tmp_if_index;
15356         }
15357       else if (unformat (input, "p %d", &priority))
15358         {
15359           priority_set = 1;
15360         }
15361       else if (unformat (input, "w %d", &weight))
15362         {
15363           weight_set = 1;
15364         }
15365       else
15366         break;
15367     }
15368
15369   if (locator_set_name_set == 0)
15370     {
15371       errmsg ("missing locator-set name");
15372       return -99;
15373     }
15374
15375   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15376     {
15377       errmsg ("missing sw_if_index");
15378       vec_free (locator_set_name);
15379       return -99;
15380     }
15381
15382   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15383     {
15384       errmsg ("cannot use both params interface name and sw_if_index");
15385       vec_free (locator_set_name);
15386       return -99;
15387     }
15388
15389   if (priority_set == 0)
15390     {
15391       errmsg ("missing locator-set priority");
15392       vec_free (locator_set_name);
15393       return -99;
15394     }
15395
15396   if (weight_set == 0)
15397     {
15398       errmsg ("missing locator-set weight");
15399       vec_free (locator_set_name);
15400       return -99;
15401     }
15402
15403   if (vec_len (locator_set_name) > 64)
15404     {
15405       errmsg ("locator-set name too long");
15406       vec_free (locator_set_name);
15407       return -99;
15408     }
15409   vec_add1 (locator_set_name, 0);
15410
15411   /* Construct the API message */
15412   M (ONE_ADD_DEL_LOCATOR, mp);
15413
15414   mp->is_add = is_add;
15415   mp->sw_if_index = ntohl (sw_if_index);
15416   mp->priority = priority;
15417   mp->weight = weight;
15418   clib_memcpy (mp->locator_set_name, locator_set_name,
15419                vec_len (locator_set_name));
15420   vec_free (locator_set_name);
15421
15422   /* send it... */
15423   S (mp);
15424
15425   /* Wait for a reply... */
15426   W (ret);
15427   return ret;
15428 }
15429
15430 #define api_lisp_add_del_locator api_one_add_del_locator
15431
15432 uword
15433 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15434 {
15435   u32 *key_id = va_arg (*args, u32 *);
15436   u8 *s = 0;
15437
15438   if (unformat (input, "%s", &s))
15439     {
15440       if (!strcmp ((char *) s, "sha1"))
15441         key_id[0] = HMAC_SHA_1_96;
15442       else if (!strcmp ((char *) s, "sha256"))
15443         key_id[0] = HMAC_SHA_256_128;
15444       else
15445         {
15446           clib_warning ("invalid key_id: '%s'", s);
15447           key_id[0] = HMAC_NO_KEY;
15448         }
15449     }
15450   else
15451     return 0;
15452
15453   vec_free (s);
15454   return 1;
15455 }
15456
15457 static int
15458 api_one_add_del_local_eid (vat_main_t * vam)
15459 {
15460   unformat_input_t *input = vam->input;
15461   vl_api_one_add_del_local_eid_t *mp;
15462   u8 is_add = 1;
15463   u8 eid_set = 0;
15464   lisp_eid_vat_t _eid, *eid = &_eid;
15465   u8 *locator_set_name = 0;
15466   u8 locator_set_name_set = 0;
15467   u32 vni = 0;
15468   u16 key_id = 0;
15469   u8 *key = 0;
15470   int ret;
15471
15472   /* Parse args required to build the message */
15473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15474     {
15475       if (unformat (input, "del"))
15476         {
15477           is_add = 0;
15478         }
15479       else if (unformat (input, "vni %d", &vni))
15480         {
15481           ;
15482         }
15483       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15484         {
15485           eid_set = 1;
15486         }
15487       else if (unformat (input, "locator-set %s", &locator_set_name))
15488         {
15489           locator_set_name_set = 1;
15490         }
15491       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15492         ;
15493       else if (unformat (input, "secret-key %_%v%_", &key))
15494         ;
15495       else
15496         break;
15497     }
15498
15499   if (locator_set_name_set == 0)
15500     {
15501       errmsg ("missing locator-set name");
15502       return -99;
15503     }
15504
15505   if (0 == eid_set)
15506     {
15507       errmsg ("EID address not set!");
15508       vec_free (locator_set_name);
15509       return -99;
15510     }
15511
15512   if (key && (0 == key_id))
15513     {
15514       errmsg ("invalid key_id!");
15515       return -99;
15516     }
15517
15518   if (vec_len (key) > 64)
15519     {
15520       errmsg ("key too long");
15521       vec_free (key);
15522       return -99;
15523     }
15524
15525   if (vec_len (locator_set_name) > 64)
15526     {
15527       errmsg ("locator-set name too long");
15528       vec_free (locator_set_name);
15529       return -99;
15530     }
15531   vec_add1 (locator_set_name, 0);
15532
15533   /* Construct the API message */
15534   M (ONE_ADD_DEL_LOCAL_EID, mp);
15535
15536   mp->is_add = is_add;
15537   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15538   mp->eid_type = eid->type;
15539   mp->prefix_len = eid->len;
15540   mp->vni = clib_host_to_net_u32 (vni);
15541   mp->key_id = clib_host_to_net_u16 (key_id);
15542   clib_memcpy (mp->locator_set_name, locator_set_name,
15543                vec_len (locator_set_name));
15544   clib_memcpy (mp->key, key, vec_len (key));
15545
15546   vec_free (locator_set_name);
15547   vec_free (key);
15548
15549   /* send it... */
15550   S (mp);
15551
15552   /* Wait for a reply... */
15553   W (ret);
15554   return ret;
15555 }
15556
15557 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15558
15559 static int
15560 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15561 {
15562   u32 dp_table = 0, vni = 0;;
15563   unformat_input_t *input = vam->input;
15564   vl_api_gpe_add_del_fwd_entry_t *mp;
15565   u8 is_add = 1;
15566   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15567   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15568   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15569   u32 action = ~0, w;
15570   ip4_address_t rmt_rloc4, lcl_rloc4;
15571   ip6_address_t rmt_rloc6, lcl_rloc6;
15572   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15573   int ret;
15574
15575   clib_memset (&rloc, 0, sizeof (rloc));
15576
15577   /* Parse args required to build the message */
15578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15579     {
15580       if (unformat (input, "del"))
15581         is_add = 0;
15582       else if (unformat (input, "add"))
15583         is_add = 1;
15584       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15585         {
15586           rmt_eid_set = 1;
15587         }
15588       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15589         {
15590           lcl_eid_set = 1;
15591         }
15592       else if (unformat (input, "vrf %d", &dp_table))
15593         ;
15594       else if (unformat (input, "bd %d", &dp_table))
15595         ;
15596       else if (unformat (input, "vni %d", &vni))
15597         ;
15598       else if (unformat (input, "w %d", &w))
15599         {
15600           if (!curr_rloc)
15601             {
15602               errmsg ("No RLOC configured for setting priority/weight!");
15603               return -99;
15604             }
15605           curr_rloc->weight = w;
15606         }
15607       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15608                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15609         {
15610           rloc.is_ip4 = 1;
15611
15612           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15613           rloc.weight = 0;
15614           vec_add1 (lcl_locs, rloc);
15615
15616           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15617           vec_add1 (rmt_locs, rloc);
15618           /* weight saved in rmt loc */
15619           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15620         }
15621       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15622                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15623         {
15624           rloc.is_ip4 = 0;
15625           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15626           rloc.weight = 0;
15627           vec_add1 (lcl_locs, rloc);
15628
15629           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15630           vec_add1 (rmt_locs, rloc);
15631           /* weight saved in rmt loc */
15632           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15633         }
15634       else if (unformat (input, "action %d", &action))
15635         {
15636           ;
15637         }
15638       else
15639         {
15640           clib_warning ("parse error '%U'", format_unformat_error, input);
15641           return -99;
15642         }
15643     }
15644
15645   if (!rmt_eid_set)
15646     {
15647       errmsg ("remote eid addresses not set");
15648       return -99;
15649     }
15650
15651   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15652     {
15653       errmsg ("eid types don't match");
15654       return -99;
15655     }
15656
15657   if (0 == rmt_locs && (u32) ~ 0 == action)
15658     {
15659       errmsg ("action not set for negative mapping");
15660       return -99;
15661     }
15662
15663   /* Construct the API message */
15664   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15665       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15666
15667   mp->is_add = is_add;
15668   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15669   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15670   mp->eid_type = rmt_eid->type;
15671   mp->dp_table = clib_host_to_net_u32 (dp_table);
15672   mp->vni = clib_host_to_net_u32 (vni);
15673   mp->rmt_len = rmt_eid->len;
15674   mp->lcl_len = lcl_eid->len;
15675   mp->action = action;
15676
15677   if (0 != rmt_locs && 0 != lcl_locs)
15678     {
15679       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15680       clib_memcpy (mp->locs, lcl_locs,
15681                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15682
15683       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15684       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15685                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15686     }
15687   vec_free (lcl_locs);
15688   vec_free (rmt_locs);
15689
15690   /* send it... */
15691   S (mp);
15692
15693   /* Wait for a reply... */
15694   W (ret);
15695   return ret;
15696 }
15697
15698 static int
15699 api_one_add_del_map_server (vat_main_t * vam)
15700 {
15701   unformat_input_t *input = vam->input;
15702   vl_api_one_add_del_map_server_t *mp;
15703   u8 is_add = 1;
15704   u8 ipv4_set = 0;
15705   u8 ipv6_set = 0;
15706   ip4_address_t ipv4;
15707   ip6_address_t ipv6;
15708   int ret;
15709
15710   /* Parse args required to build the message */
15711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15712     {
15713       if (unformat (input, "del"))
15714         {
15715           is_add = 0;
15716         }
15717       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15718         {
15719           ipv4_set = 1;
15720         }
15721       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15722         {
15723           ipv6_set = 1;
15724         }
15725       else
15726         break;
15727     }
15728
15729   if (ipv4_set && ipv6_set)
15730     {
15731       errmsg ("both eid v4 and v6 addresses set");
15732       return -99;
15733     }
15734
15735   if (!ipv4_set && !ipv6_set)
15736     {
15737       errmsg ("eid addresses not set");
15738       return -99;
15739     }
15740
15741   /* Construct the API message */
15742   M (ONE_ADD_DEL_MAP_SERVER, mp);
15743
15744   mp->is_add = is_add;
15745   if (ipv6_set)
15746     {
15747       mp->is_ipv6 = 1;
15748       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15749     }
15750   else
15751     {
15752       mp->is_ipv6 = 0;
15753       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15754     }
15755
15756   /* send it... */
15757   S (mp);
15758
15759   /* Wait for a reply... */
15760   W (ret);
15761   return ret;
15762 }
15763
15764 #define api_lisp_add_del_map_server api_one_add_del_map_server
15765
15766 static int
15767 api_one_add_del_map_resolver (vat_main_t * vam)
15768 {
15769   unformat_input_t *input = vam->input;
15770   vl_api_one_add_del_map_resolver_t *mp;
15771   u8 is_add = 1;
15772   u8 ipv4_set = 0;
15773   u8 ipv6_set = 0;
15774   ip4_address_t ipv4;
15775   ip6_address_t ipv6;
15776   int ret;
15777
15778   /* Parse args required to build the message */
15779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15780     {
15781       if (unformat (input, "del"))
15782         {
15783           is_add = 0;
15784         }
15785       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15786         {
15787           ipv4_set = 1;
15788         }
15789       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15790         {
15791           ipv6_set = 1;
15792         }
15793       else
15794         break;
15795     }
15796
15797   if (ipv4_set && ipv6_set)
15798     {
15799       errmsg ("both eid v4 and v6 addresses set");
15800       return -99;
15801     }
15802
15803   if (!ipv4_set && !ipv6_set)
15804     {
15805       errmsg ("eid addresses not set");
15806       return -99;
15807     }
15808
15809   /* Construct the API message */
15810   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15811
15812   mp->is_add = is_add;
15813   if (ipv6_set)
15814     {
15815       mp->is_ipv6 = 1;
15816       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15817     }
15818   else
15819     {
15820       mp->is_ipv6 = 0;
15821       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15822     }
15823
15824   /* send it... */
15825   S (mp);
15826
15827   /* Wait for a reply... */
15828   W (ret);
15829   return ret;
15830 }
15831
15832 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15833
15834 static int
15835 api_lisp_gpe_enable_disable (vat_main_t * vam)
15836 {
15837   unformat_input_t *input = vam->input;
15838   vl_api_gpe_enable_disable_t *mp;
15839   u8 is_set = 0;
15840   u8 is_en = 1;
15841   int ret;
15842
15843   /* Parse args required to build the message */
15844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15845     {
15846       if (unformat (input, "enable"))
15847         {
15848           is_set = 1;
15849           is_en = 1;
15850         }
15851       else if (unformat (input, "disable"))
15852         {
15853           is_set = 1;
15854           is_en = 0;
15855         }
15856       else
15857         break;
15858     }
15859
15860   if (is_set == 0)
15861     {
15862       errmsg ("Value not set");
15863       return -99;
15864     }
15865
15866   /* Construct the API message */
15867   M (GPE_ENABLE_DISABLE, mp);
15868
15869   mp->is_en = is_en;
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Wait for a reply... */
15875   W (ret);
15876   return ret;
15877 }
15878
15879 static int
15880 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15881 {
15882   unformat_input_t *input = vam->input;
15883   vl_api_one_rloc_probe_enable_disable_t *mp;
15884   u8 is_set = 0;
15885   u8 is_en = 0;
15886   int ret;
15887
15888   /* Parse args required to build the message */
15889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15890     {
15891       if (unformat (input, "enable"))
15892         {
15893           is_set = 1;
15894           is_en = 1;
15895         }
15896       else if (unformat (input, "disable"))
15897         is_set = 1;
15898       else
15899         break;
15900     }
15901
15902   if (!is_set)
15903     {
15904       errmsg ("Value not set");
15905       return -99;
15906     }
15907
15908   /* Construct the API message */
15909   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15910
15911   mp->is_enabled = is_en;
15912
15913   /* send it... */
15914   S (mp);
15915
15916   /* Wait for a reply... */
15917   W (ret);
15918   return ret;
15919 }
15920
15921 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15922
15923 static int
15924 api_one_map_register_enable_disable (vat_main_t * vam)
15925 {
15926   unformat_input_t *input = vam->input;
15927   vl_api_one_map_register_enable_disable_t *mp;
15928   u8 is_set = 0;
15929   u8 is_en = 0;
15930   int ret;
15931
15932   /* Parse args required to build the message */
15933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15934     {
15935       if (unformat (input, "enable"))
15936         {
15937           is_set = 1;
15938           is_en = 1;
15939         }
15940       else if (unformat (input, "disable"))
15941         is_set = 1;
15942       else
15943         break;
15944     }
15945
15946   if (!is_set)
15947     {
15948       errmsg ("Value not set");
15949       return -99;
15950     }
15951
15952   /* Construct the API message */
15953   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15954
15955   mp->is_enabled = is_en;
15956
15957   /* send it... */
15958   S (mp);
15959
15960   /* Wait for a reply... */
15961   W (ret);
15962   return ret;
15963 }
15964
15965 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15966
15967 static int
15968 api_one_enable_disable (vat_main_t * vam)
15969 {
15970   unformat_input_t *input = vam->input;
15971   vl_api_one_enable_disable_t *mp;
15972   u8 is_set = 0;
15973   u8 is_en = 0;
15974   int ret;
15975
15976   /* Parse args required to build the message */
15977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15978     {
15979       if (unformat (input, "enable"))
15980         {
15981           is_set = 1;
15982           is_en = 1;
15983         }
15984       else if (unformat (input, "disable"))
15985         {
15986           is_set = 1;
15987         }
15988       else
15989         break;
15990     }
15991
15992   if (!is_set)
15993     {
15994       errmsg ("Value not set");
15995       return -99;
15996     }
15997
15998   /* Construct the API message */
15999   M (ONE_ENABLE_DISABLE, mp);
16000
16001   mp->is_en = is_en;
16002
16003   /* send it... */
16004   S (mp);
16005
16006   /* Wait for a reply... */
16007   W (ret);
16008   return ret;
16009 }
16010
16011 #define api_lisp_enable_disable api_one_enable_disable
16012
16013 static int
16014 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16015 {
16016   unformat_input_t *input = vam->input;
16017   vl_api_one_enable_disable_xtr_mode_t *mp;
16018   u8 is_set = 0;
16019   u8 is_en = 0;
16020   int ret;
16021
16022   /* Parse args required to build the message */
16023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16024     {
16025       if (unformat (input, "enable"))
16026         {
16027           is_set = 1;
16028           is_en = 1;
16029         }
16030       else if (unformat (input, "disable"))
16031         {
16032           is_set = 1;
16033         }
16034       else
16035         break;
16036     }
16037
16038   if (!is_set)
16039     {
16040       errmsg ("Value not set");
16041       return -99;
16042     }
16043
16044   /* Construct the API message */
16045   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16046
16047   mp->is_en = is_en;
16048
16049   /* send it... */
16050   S (mp);
16051
16052   /* Wait for a reply... */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_one_show_xtr_mode (vat_main_t * vam)
16059 {
16060   vl_api_one_show_xtr_mode_t *mp;
16061   int ret;
16062
16063   /* Construct the API message */
16064   M (ONE_SHOW_XTR_MODE, mp);
16065
16066   /* send it... */
16067   S (mp);
16068
16069   /* Wait for a reply... */
16070   W (ret);
16071   return ret;
16072 }
16073
16074 static int
16075 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16076 {
16077   unformat_input_t *input = vam->input;
16078   vl_api_one_enable_disable_pitr_mode_t *mp;
16079   u8 is_set = 0;
16080   u8 is_en = 0;
16081   int ret;
16082
16083   /* Parse args required to build the message */
16084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16085     {
16086       if (unformat (input, "enable"))
16087         {
16088           is_set = 1;
16089           is_en = 1;
16090         }
16091       else if (unformat (input, "disable"))
16092         {
16093           is_set = 1;
16094         }
16095       else
16096         break;
16097     }
16098
16099   if (!is_set)
16100     {
16101       errmsg ("Value not set");
16102       return -99;
16103     }
16104
16105   /* Construct the API message */
16106   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16107
16108   mp->is_en = is_en;
16109
16110   /* send it... */
16111   S (mp);
16112
16113   /* Wait for a reply... */
16114   W (ret);
16115   return ret;
16116 }
16117
16118 static int
16119 api_one_show_pitr_mode (vat_main_t * vam)
16120 {
16121   vl_api_one_show_pitr_mode_t *mp;
16122   int ret;
16123
16124   /* Construct the API message */
16125   M (ONE_SHOW_PITR_MODE, mp);
16126
16127   /* send it... */
16128   S (mp);
16129
16130   /* Wait for a reply... */
16131   W (ret);
16132   return ret;
16133 }
16134
16135 static int
16136 api_one_enable_disable_petr_mode (vat_main_t * vam)
16137 {
16138   unformat_input_t *input = vam->input;
16139   vl_api_one_enable_disable_petr_mode_t *mp;
16140   u8 is_set = 0;
16141   u8 is_en = 0;
16142   int ret;
16143
16144   /* Parse args required to build the message */
16145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16146     {
16147       if (unformat (input, "enable"))
16148         {
16149           is_set = 1;
16150           is_en = 1;
16151         }
16152       else if (unformat (input, "disable"))
16153         {
16154           is_set = 1;
16155         }
16156       else
16157         break;
16158     }
16159
16160   if (!is_set)
16161     {
16162       errmsg ("Value not set");
16163       return -99;
16164     }
16165
16166   /* Construct the API message */
16167   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16168
16169   mp->is_en = is_en;
16170
16171   /* send it... */
16172   S (mp);
16173
16174   /* Wait for a reply... */
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_one_show_petr_mode (vat_main_t * vam)
16181 {
16182   vl_api_one_show_petr_mode_t *mp;
16183   int ret;
16184
16185   /* Construct the API message */
16186   M (ONE_SHOW_PETR_MODE, mp);
16187
16188   /* send it... */
16189   S (mp);
16190
16191   /* Wait for a reply... */
16192   W (ret);
16193   return ret;
16194 }
16195
16196 static int
16197 api_show_one_map_register_state (vat_main_t * vam)
16198 {
16199   vl_api_show_one_map_register_state_t *mp;
16200   int ret;
16201
16202   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16203
16204   /* send */
16205   S (mp);
16206
16207   /* wait for reply */
16208   W (ret);
16209   return ret;
16210 }
16211
16212 #define api_show_lisp_map_register_state api_show_one_map_register_state
16213
16214 static int
16215 api_show_one_rloc_probe_state (vat_main_t * vam)
16216 {
16217   vl_api_show_one_rloc_probe_state_t *mp;
16218   int ret;
16219
16220   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16221
16222   /* send */
16223   S (mp);
16224
16225   /* wait for reply */
16226   W (ret);
16227   return ret;
16228 }
16229
16230 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16231
16232 static int
16233 api_one_add_del_ndp_entry (vat_main_t * vam)
16234 {
16235   vl_api_one_add_del_ndp_entry_t *mp;
16236   unformat_input_t *input = vam->input;
16237   u8 is_add = 1;
16238   u8 mac_set = 0;
16239   u8 bd_set = 0;
16240   u8 ip_set = 0;
16241   u8 mac[6] = { 0, };
16242   u8 ip6[16] = { 0, };
16243   u32 bd = ~0;
16244   int ret;
16245
16246   /* Parse args required to build the message */
16247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16248     {
16249       if (unformat (input, "del"))
16250         is_add = 0;
16251       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16252         mac_set = 1;
16253       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16254         ip_set = 1;
16255       else if (unformat (input, "bd %d", &bd))
16256         bd_set = 1;
16257       else
16258         {
16259           errmsg ("parse error '%U'", format_unformat_error, input);
16260           return -99;
16261         }
16262     }
16263
16264   if (!bd_set || !ip_set || (!mac_set && is_add))
16265     {
16266       errmsg ("Missing BD, IP or MAC!");
16267       return -99;
16268     }
16269
16270   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16271   mp->is_add = is_add;
16272   clib_memcpy (mp->mac, mac, 6);
16273   mp->bd = clib_host_to_net_u32 (bd);
16274   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16275
16276   /* send */
16277   S (mp);
16278
16279   /* wait for reply */
16280   W (ret);
16281   return ret;
16282 }
16283
16284 static int
16285 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16286 {
16287   vl_api_one_add_del_l2_arp_entry_t *mp;
16288   unformat_input_t *input = vam->input;
16289   u8 is_add = 1;
16290   u8 mac_set = 0;
16291   u8 bd_set = 0;
16292   u8 ip_set = 0;
16293   u8 mac[6] = { 0, };
16294   u32 ip4 = 0, bd = ~0;
16295   int ret;
16296
16297   /* Parse args required to build the message */
16298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16299     {
16300       if (unformat (input, "del"))
16301         is_add = 0;
16302       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16303         mac_set = 1;
16304       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16305         ip_set = 1;
16306       else if (unformat (input, "bd %d", &bd))
16307         bd_set = 1;
16308       else
16309         {
16310           errmsg ("parse error '%U'", format_unformat_error, input);
16311           return -99;
16312         }
16313     }
16314
16315   if (!bd_set || !ip_set || (!mac_set && is_add))
16316     {
16317       errmsg ("Missing BD, IP or MAC!");
16318       return -99;
16319     }
16320
16321   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16322   mp->is_add = is_add;
16323   clib_memcpy (mp->mac, mac, 6);
16324   mp->bd = clib_host_to_net_u32 (bd);
16325   mp->ip4 = ip4;
16326
16327   /* send */
16328   S (mp);
16329
16330   /* wait for reply */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_one_ndp_bd_get (vat_main_t * vam)
16337 {
16338   vl_api_one_ndp_bd_get_t *mp;
16339   int ret;
16340
16341   M (ONE_NDP_BD_GET, mp);
16342
16343   /* send */
16344   S (mp);
16345
16346   /* wait for reply */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_one_ndp_entries_get (vat_main_t * vam)
16353 {
16354   vl_api_one_ndp_entries_get_t *mp;
16355   unformat_input_t *input = vam->input;
16356   u8 bd_set = 0;
16357   u32 bd = ~0;
16358   int ret;
16359
16360   /* Parse args required to build the message */
16361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16362     {
16363       if (unformat (input, "bd %d", &bd))
16364         bd_set = 1;
16365       else
16366         {
16367           errmsg ("parse error '%U'", format_unformat_error, input);
16368           return -99;
16369         }
16370     }
16371
16372   if (!bd_set)
16373     {
16374       errmsg ("Expected bridge domain!");
16375       return -99;
16376     }
16377
16378   M (ONE_NDP_ENTRIES_GET, mp);
16379   mp->bd = clib_host_to_net_u32 (bd);
16380
16381   /* send */
16382   S (mp);
16383
16384   /* wait for reply */
16385   W (ret);
16386   return ret;
16387 }
16388
16389 static int
16390 api_one_l2_arp_bd_get (vat_main_t * vam)
16391 {
16392   vl_api_one_l2_arp_bd_get_t *mp;
16393   int ret;
16394
16395   M (ONE_L2_ARP_BD_GET, mp);
16396
16397   /* send */
16398   S (mp);
16399
16400   /* wait for reply */
16401   W (ret);
16402   return ret;
16403 }
16404
16405 static int
16406 api_one_l2_arp_entries_get (vat_main_t * vam)
16407 {
16408   vl_api_one_l2_arp_entries_get_t *mp;
16409   unformat_input_t *input = vam->input;
16410   u8 bd_set = 0;
16411   u32 bd = ~0;
16412   int ret;
16413
16414   /* Parse args required to build the message */
16415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16416     {
16417       if (unformat (input, "bd %d", &bd))
16418         bd_set = 1;
16419       else
16420         {
16421           errmsg ("parse error '%U'", format_unformat_error, input);
16422           return -99;
16423         }
16424     }
16425
16426   if (!bd_set)
16427     {
16428       errmsg ("Expected bridge domain!");
16429       return -99;
16430     }
16431
16432   M (ONE_L2_ARP_ENTRIES_GET, mp);
16433   mp->bd = clib_host_to_net_u32 (bd);
16434
16435   /* send */
16436   S (mp);
16437
16438   /* wait for reply */
16439   W (ret);
16440   return ret;
16441 }
16442
16443 static int
16444 api_one_stats_enable_disable (vat_main_t * vam)
16445 {
16446   vl_api_one_stats_enable_disable_t *mp;
16447   unformat_input_t *input = vam->input;
16448   u8 is_set = 0;
16449   u8 is_en = 0;
16450   int ret;
16451
16452   /* Parse args required to build the message */
16453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16454     {
16455       if (unformat (input, "enable"))
16456         {
16457           is_set = 1;
16458           is_en = 1;
16459         }
16460       else if (unformat (input, "disable"))
16461         {
16462           is_set = 1;
16463         }
16464       else
16465         break;
16466     }
16467
16468   if (!is_set)
16469     {
16470       errmsg ("Value not set");
16471       return -99;
16472     }
16473
16474   M (ONE_STATS_ENABLE_DISABLE, mp);
16475   mp->is_en = is_en;
16476
16477   /* send */
16478   S (mp);
16479
16480   /* wait for reply */
16481   W (ret);
16482   return ret;
16483 }
16484
16485 static int
16486 api_show_one_stats_enable_disable (vat_main_t * vam)
16487 {
16488   vl_api_show_one_stats_enable_disable_t *mp;
16489   int ret;
16490
16491   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16492
16493   /* send */
16494   S (mp);
16495
16496   /* wait for reply */
16497   W (ret);
16498   return ret;
16499 }
16500
16501 static int
16502 api_show_one_map_request_mode (vat_main_t * vam)
16503 {
16504   vl_api_show_one_map_request_mode_t *mp;
16505   int ret;
16506
16507   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16508
16509   /* send */
16510   S (mp);
16511
16512   /* wait for reply */
16513   W (ret);
16514   return ret;
16515 }
16516
16517 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16518
16519 static int
16520 api_one_map_request_mode (vat_main_t * vam)
16521 {
16522   unformat_input_t *input = vam->input;
16523   vl_api_one_map_request_mode_t *mp;
16524   u8 mode = 0;
16525   int ret;
16526
16527   /* Parse args required to build the message */
16528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16529     {
16530       if (unformat (input, "dst-only"))
16531         mode = 0;
16532       else if (unformat (input, "src-dst"))
16533         mode = 1;
16534       else
16535         {
16536           errmsg ("parse error '%U'", format_unformat_error, input);
16537           return -99;
16538         }
16539     }
16540
16541   M (ONE_MAP_REQUEST_MODE, mp);
16542
16543   mp->mode = mode;
16544
16545   /* send */
16546   S (mp);
16547
16548   /* wait for reply */
16549   W (ret);
16550   return ret;
16551 }
16552
16553 #define api_lisp_map_request_mode api_one_map_request_mode
16554
16555 /**
16556  * Enable/disable ONE proxy ITR.
16557  *
16558  * @param vam vpp API test context
16559  * @return return code
16560  */
16561 static int
16562 api_one_pitr_set_locator_set (vat_main_t * vam)
16563 {
16564   u8 ls_name_set = 0;
16565   unformat_input_t *input = vam->input;
16566   vl_api_one_pitr_set_locator_set_t *mp;
16567   u8 is_add = 1;
16568   u8 *ls_name = 0;
16569   int ret;
16570
16571   /* Parse args required to build the message */
16572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16573     {
16574       if (unformat (input, "del"))
16575         is_add = 0;
16576       else if (unformat (input, "locator-set %s", &ls_name))
16577         ls_name_set = 1;
16578       else
16579         {
16580           errmsg ("parse error '%U'", format_unformat_error, input);
16581           return -99;
16582         }
16583     }
16584
16585   if (!ls_name_set)
16586     {
16587       errmsg ("locator-set name not set!");
16588       return -99;
16589     }
16590
16591   M (ONE_PITR_SET_LOCATOR_SET, mp);
16592
16593   mp->is_add = is_add;
16594   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16595   vec_free (ls_name);
16596
16597   /* send */
16598   S (mp);
16599
16600   /* wait for reply */
16601   W (ret);
16602   return ret;
16603 }
16604
16605 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16606
16607 static int
16608 api_one_nsh_set_locator_set (vat_main_t * vam)
16609 {
16610   u8 ls_name_set = 0;
16611   unformat_input_t *input = vam->input;
16612   vl_api_one_nsh_set_locator_set_t *mp;
16613   u8 is_add = 1;
16614   u8 *ls_name = 0;
16615   int ret;
16616
16617   /* Parse args required to build the message */
16618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16619     {
16620       if (unformat (input, "del"))
16621         is_add = 0;
16622       else if (unformat (input, "ls %s", &ls_name))
16623         ls_name_set = 1;
16624       else
16625         {
16626           errmsg ("parse error '%U'", format_unformat_error, input);
16627           return -99;
16628         }
16629     }
16630
16631   if (!ls_name_set && is_add)
16632     {
16633       errmsg ("locator-set name not set!");
16634       return -99;
16635     }
16636
16637   M (ONE_NSH_SET_LOCATOR_SET, mp);
16638
16639   mp->is_add = is_add;
16640   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16641   vec_free (ls_name);
16642
16643   /* send */
16644   S (mp);
16645
16646   /* wait for reply */
16647   W (ret);
16648   return ret;
16649 }
16650
16651 static int
16652 api_show_one_pitr (vat_main_t * vam)
16653 {
16654   vl_api_show_one_pitr_t *mp;
16655   int ret;
16656
16657   if (!vam->json_output)
16658     {
16659       print (vam->ofp, "%=20s", "lisp status:");
16660     }
16661
16662   M (SHOW_ONE_PITR, mp);
16663   /* send it... */
16664   S (mp);
16665
16666   /* Wait for a reply... */
16667   W (ret);
16668   return ret;
16669 }
16670
16671 #define api_show_lisp_pitr api_show_one_pitr
16672
16673 static int
16674 api_one_use_petr (vat_main_t * vam)
16675 {
16676   unformat_input_t *input = vam->input;
16677   vl_api_one_use_petr_t *mp;
16678   u8 is_add = 0;
16679   ip_address_t ip;
16680   int ret;
16681
16682   clib_memset (&ip, 0, sizeof (ip));
16683
16684   /* Parse args required to build the message */
16685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16686     {
16687       if (unformat (input, "disable"))
16688         is_add = 0;
16689       else
16690         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16691         {
16692           is_add = 1;
16693           ip_addr_version (&ip) = IP4;
16694         }
16695       else
16696         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16697         {
16698           is_add = 1;
16699           ip_addr_version (&ip) = IP6;
16700         }
16701       else
16702         {
16703           errmsg ("parse error '%U'", format_unformat_error, input);
16704           return -99;
16705         }
16706     }
16707
16708   M (ONE_USE_PETR, mp);
16709
16710   mp->is_add = is_add;
16711   if (is_add)
16712     {
16713       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16714       if (mp->is_ip4)
16715         clib_memcpy (mp->address, &ip, 4);
16716       else
16717         clib_memcpy (mp->address, &ip, 16);
16718     }
16719
16720   /* send */
16721   S (mp);
16722
16723   /* wait for reply */
16724   W (ret);
16725   return ret;
16726 }
16727
16728 #define api_lisp_use_petr api_one_use_petr
16729
16730 static int
16731 api_show_one_nsh_mapping (vat_main_t * vam)
16732 {
16733   vl_api_show_one_use_petr_t *mp;
16734   int ret;
16735
16736   if (!vam->json_output)
16737     {
16738       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16739     }
16740
16741   M (SHOW_ONE_NSH_MAPPING, mp);
16742   /* send it... */
16743   S (mp);
16744
16745   /* Wait for a reply... */
16746   W (ret);
16747   return ret;
16748 }
16749
16750 static int
16751 api_show_one_use_petr (vat_main_t * vam)
16752 {
16753   vl_api_show_one_use_petr_t *mp;
16754   int ret;
16755
16756   if (!vam->json_output)
16757     {
16758       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16759     }
16760
16761   M (SHOW_ONE_USE_PETR, mp);
16762   /* send it... */
16763   S (mp);
16764
16765   /* Wait for a reply... */
16766   W (ret);
16767   return ret;
16768 }
16769
16770 #define api_show_lisp_use_petr api_show_one_use_petr
16771
16772 /**
16773  * Add/delete mapping between vni and vrf
16774  */
16775 static int
16776 api_one_eid_table_add_del_map (vat_main_t * vam)
16777 {
16778   unformat_input_t *input = vam->input;
16779   vl_api_one_eid_table_add_del_map_t *mp;
16780   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16781   u32 vni, vrf, bd_index;
16782   int ret;
16783
16784   /* Parse args required to build the message */
16785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16786     {
16787       if (unformat (input, "del"))
16788         is_add = 0;
16789       else if (unformat (input, "vrf %d", &vrf))
16790         vrf_set = 1;
16791       else if (unformat (input, "bd_index %d", &bd_index))
16792         bd_index_set = 1;
16793       else if (unformat (input, "vni %d", &vni))
16794         vni_set = 1;
16795       else
16796         break;
16797     }
16798
16799   if (!vni_set || (!vrf_set && !bd_index_set))
16800     {
16801       errmsg ("missing arguments!");
16802       return -99;
16803     }
16804
16805   if (vrf_set && bd_index_set)
16806     {
16807       errmsg ("error: both vrf and bd entered!");
16808       return -99;
16809     }
16810
16811   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16812
16813   mp->is_add = is_add;
16814   mp->vni = htonl (vni);
16815   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16816   mp->is_l2 = bd_index_set;
16817
16818   /* send */
16819   S (mp);
16820
16821   /* wait for reply */
16822   W (ret);
16823   return ret;
16824 }
16825
16826 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16827
16828 uword
16829 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16830 {
16831   u32 *action = va_arg (*args, u32 *);
16832   u8 *s = 0;
16833
16834   if (unformat (input, "%s", &s))
16835     {
16836       if (!strcmp ((char *) s, "no-action"))
16837         action[0] = 0;
16838       else if (!strcmp ((char *) s, "natively-forward"))
16839         action[0] = 1;
16840       else if (!strcmp ((char *) s, "send-map-request"))
16841         action[0] = 2;
16842       else if (!strcmp ((char *) s, "drop"))
16843         action[0] = 3;
16844       else
16845         {
16846           clib_warning ("invalid action: '%s'", s);
16847           action[0] = 3;
16848         }
16849     }
16850   else
16851     return 0;
16852
16853   vec_free (s);
16854   return 1;
16855 }
16856
16857 /**
16858  * Add/del remote mapping to/from ONE control plane
16859  *
16860  * @param vam vpp API test context
16861  * @return return code
16862  */
16863 static int
16864 api_one_add_del_remote_mapping (vat_main_t * vam)
16865 {
16866   unformat_input_t *input = vam->input;
16867   vl_api_one_add_del_remote_mapping_t *mp;
16868   u32 vni = 0;
16869   lisp_eid_vat_t _eid, *eid = &_eid;
16870   lisp_eid_vat_t _seid, *seid = &_seid;
16871   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16872   u32 action = ~0, p, w, data_len;
16873   ip4_address_t rloc4;
16874   ip6_address_t rloc6;
16875   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16876   int ret;
16877
16878   clib_memset (&rloc, 0, sizeof (rloc));
16879
16880   /* Parse args required to build the message */
16881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16882     {
16883       if (unformat (input, "del-all"))
16884         {
16885           del_all = 1;
16886         }
16887       else if (unformat (input, "del"))
16888         {
16889           is_add = 0;
16890         }
16891       else if (unformat (input, "add"))
16892         {
16893           is_add = 1;
16894         }
16895       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16896         {
16897           eid_set = 1;
16898         }
16899       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16900         {
16901           seid_set = 1;
16902         }
16903       else if (unformat (input, "vni %d", &vni))
16904         {
16905           ;
16906         }
16907       else if (unformat (input, "p %d w %d", &p, &w))
16908         {
16909           if (!curr_rloc)
16910             {
16911               errmsg ("No RLOC configured for setting priority/weight!");
16912               return -99;
16913             }
16914           curr_rloc->priority = p;
16915           curr_rloc->weight = w;
16916         }
16917       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16918         {
16919           rloc.is_ip4 = 1;
16920           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16921           vec_add1 (rlocs, rloc);
16922           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16923         }
16924       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16925         {
16926           rloc.is_ip4 = 0;
16927           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16928           vec_add1 (rlocs, rloc);
16929           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16930         }
16931       else if (unformat (input, "action %U",
16932                          unformat_negative_mapping_action, &action))
16933         {
16934           ;
16935         }
16936       else
16937         {
16938           clib_warning ("parse error '%U'", format_unformat_error, input);
16939           return -99;
16940         }
16941     }
16942
16943   if (0 == eid_set)
16944     {
16945       errmsg ("missing params!");
16946       return -99;
16947     }
16948
16949   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16950     {
16951       errmsg ("no action set for negative map-reply!");
16952       return -99;
16953     }
16954
16955   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16956
16957   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16958   mp->is_add = is_add;
16959   mp->vni = htonl (vni);
16960   mp->action = (u8) action;
16961   mp->is_src_dst = seid_set;
16962   mp->eid_len = eid->len;
16963   mp->seid_len = seid->len;
16964   mp->del_all = del_all;
16965   mp->eid_type = eid->type;
16966   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16967   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16968
16969   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16970   clib_memcpy (mp->rlocs, rlocs, data_len);
16971   vec_free (rlocs);
16972
16973   /* send it... */
16974   S (mp);
16975
16976   /* Wait for a reply... */
16977   W (ret);
16978   return ret;
16979 }
16980
16981 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16982
16983 /**
16984  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16985  * forwarding entries in data-plane accordingly.
16986  *
16987  * @param vam vpp API test context
16988  * @return return code
16989  */
16990 static int
16991 api_one_add_del_adjacency (vat_main_t * vam)
16992 {
16993   unformat_input_t *input = vam->input;
16994   vl_api_one_add_del_adjacency_t *mp;
16995   u32 vni = 0;
16996   ip4_address_t leid4, reid4;
16997   ip6_address_t leid6, reid6;
16998   u8 reid_mac[6] = { 0 };
16999   u8 leid_mac[6] = { 0 };
17000   u8 reid_type, leid_type;
17001   u32 leid_len = 0, reid_len = 0, len;
17002   u8 is_add = 1;
17003   int ret;
17004
17005   leid_type = reid_type = (u8) ~ 0;
17006
17007   /* Parse args required to build the message */
17008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17009     {
17010       if (unformat (input, "del"))
17011         {
17012           is_add = 0;
17013         }
17014       else if (unformat (input, "add"))
17015         {
17016           is_add = 1;
17017         }
17018       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17019                          &reid4, &len))
17020         {
17021           reid_type = 0;        /* ipv4 */
17022           reid_len = len;
17023         }
17024       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17025                          &reid6, &len))
17026         {
17027           reid_type = 1;        /* ipv6 */
17028           reid_len = len;
17029         }
17030       else if (unformat (input, "reid %U", unformat_ethernet_address,
17031                          reid_mac))
17032         {
17033           reid_type = 2;        /* mac */
17034         }
17035       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17036                          &leid4, &len))
17037         {
17038           leid_type = 0;        /* ipv4 */
17039           leid_len = len;
17040         }
17041       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17042                          &leid6, &len))
17043         {
17044           leid_type = 1;        /* ipv6 */
17045           leid_len = len;
17046         }
17047       else if (unformat (input, "leid %U", unformat_ethernet_address,
17048                          leid_mac))
17049         {
17050           leid_type = 2;        /* mac */
17051         }
17052       else if (unformat (input, "vni %d", &vni))
17053         {
17054           ;
17055         }
17056       else
17057         {
17058           errmsg ("parse error '%U'", format_unformat_error, input);
17059           return -99;
17060         }
17061     }
17062
17063   if ((u8) ~ 0 == reid_type)
17064     {
17065       errmsg ("missing params!");
17066       return -99;
17067     }
17068
17069   if (leid_type != reid_type)
17070     {
17071       errmsg ("remote and local EIDs are of different types!");
17072       return -99;
17073     }
17074
17075   M (ONE_ADD_DEL_ADJACENCY, mp);
17076   mp->is_add = is_add;
17077   mp->vni = htonl (vni);
17078   mp->leid_len = leid_len;
17079   mp->reid_len = reid_len;
17080   mp->eid_type = reid_type;
17081
17082   switch (mp->eid_type)
17083     {
17084     case 0:
17085       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17086       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17087       break;
17088     case 1:
17089       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17090       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17091       break;
17092     case 2:
17093       clib_memcpy (mp->leid, leid_mac, 6);
17094       clib_memcpy (mp->reid, reid_mac, 6);
17095       break;
17096     default:
17097       errmsg ("unknown EID type %d!", mp->eid_type);
17098       return 0;
17099     }
17100
17101   /* send it... */
17102   S (mp);
17103
17104   /* Wait for a reply... */
17105   W (ret);
17106   return ret;
17107 }
17108
17109 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17110
17111 uword
17112 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17113 {
17114   u32 *mode = va_arg (*args, u32 *);
17115
17116   if (unformat (input, "lisp"))
17117     *mode = 0;
17118   else if (unformat (input, "vxlan"))
17119     *mode = 1;
17120   else
17121     return 0;
17122
17123   return 1;
17124 }
17125
17126 static int
17127 api_gpe_get_encap_mode (vat_main_t * vam)
17128 {
17129   vl_api_gpe_get_encap_mode_t *mp;
17130   int ret;
17131
17132   /* Construct the API message */
17133   M (GPE_GET_ENCAP_MODE, mp);
17134
17135   /* send it... */
17136   S (mp);
17137
17138   /* Wait for a reply... */
17139   W (ret);
17140   return ret;
17141 }
17142
17143 static int
17144 api_gpe_set_encap_mode (vat_main_t * vam)
17145 {
17146   unformat_input_t *input = vam->input;
17147   vl_api_gpe_set_encap_mode_t *mp;
17148   int ret;
17149   u32 mode = 0;
17150
17151   /* Parse args required to build the message */
17152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17153     {
17154       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17155         ;
17156       else
17157         break;
17158     }
17159
17160   /* Construct the API message */
17161   M (GPE_SET_ENCAP_MODE, mp);
17162
17163   mp->mode = mode;
17164
17165   /* send it... */
17166   S (mp);
17167
17168   /* Wait for a reply... */
17169   W (ret);
17170   return ret;
17171 }
17172
17173 static int
17174 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17175 {
17176   unformat_input_t *input = vam->input;
17177   vl_api_gpe_add_del_iface_t *mp;
17178   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17179   u32 dp_table = 0, vni = 0;
17180   int ret;
17181
17182   /* Parse args required to build the message */
17183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17184     {
17185       if (unformat (input, "up"))
17186         {
17187           action_set = 1;
17188           is_add = 1;
17189         }
17190       else if (unformat (input, "down"))
17191         {
17192           action_set = 1;
17193           is_add = 0;
17194         }
17195       else if (unformat (input, "table_id %d", &dp_table))
17196         {
17197           dp_table_set = 1;
17198         }
17199       else if (unformat (input, "bd_id %d", &dp_table))
17200         {
17201           dp_table_set = 1;
17202           is_l2 = 1;
17203         }
17204       else if (unformat (input, "vni %d", &vni))
17205         {
17206           vni_set = 1;
17207         }
17208       else
17209         break;
17210     }
17211
17212   if (action_set == 0)
17213     {
17214       errmsg ("Action not set");
17215       return -99;
17216     }
17217   if (dp_table_set == 0 || vni_set == 0)
17218     {
17219       errmsg ("vni and dp_table must be set");
17220       return -99;
17221     }
17222
17223   /* Construct the API message */
17224   M (GPE_ADD_DEL_IFACE, mp);
17225
17226   mp->is_add = is_add;
17227   mp->dp_table = clib_host_to_net_u32 (dp_table);
17228   mp->is_l2 = is_l2;
17229   mp->vni = clib_host_to_net_u32 (vni);
17230
17231   /* send it... */
17232   S (mp);
17233
17234   /* Wait for a reply... */
17235   W (ret);
17236   return ret;
17237 }
17238
17239 static int
17240 api_one_map_register_fallback_threshold (vat_main_t * vam)
17241 {
17242   unformat_input_t *input = vam->input;
17243   vl_api_one_map_register_fallback_threshold_t *mp;
17244   u32 value = 0;
17245   u8 is_set = 0;
17246   int ret;
17247
17248   /* Parse args required to build the message */
17249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17250     {
17251       if (unformat (input, "%u", &value))
17252         is_set = 1;
17253       else
17254         {
17255           clib_warning ("parse error '%U'", format_unformat_error, input);
17256           return -99;
17257         }
17258     }
17259
17260   if (!is_set)
17261     {
17262       errmsg ("fallback threshold value is missing!");
17263       return -99;
17264     }
17265
17266   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17267   mp->value = clib_host_to_net_u32 (value);
17268
17269   /* send it... */
17270   S (mp);
17271
17272   /* Wait for a reply... */
17273   W (ret);
17274   return ret;
17275 }
17276
17277 static int
17278 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17279 {
17280   vl_api_show_one_map_register_fallback_threshold_t *mp;
17281   int ret;
17282
17283   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17284
17285   /* send it... */
17286   S (mp);
17287
17288   /* Wait for a reply... */
17289   W (ret);
17290   return ret;
17291 }
17292
17293 uword
17294 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17295 {
17296   u32 *proto = va_arg (*args, u32 *);
17297
17298   if (unformat (input, "udp"))
17299     *proto = 1;
17300   else if (unformat (input, "api"))
17301     *proto = 2;
17302   else
17303     return 0;
17304
17305   return 1;
17306 }
17307
17308 static int
17309 api_one_set_transport_protocol (vat_main_t * vam)
17310 {
17311   unformat_input_t *input = vam->input;
17312   vl_api_one_set_transport_protocol_t *mp;
17313   u8 is_set = 0;
17314   u32 protocol = 0;
17315   int ret;
17316
17317   /* Parse args required to build the message */
17318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17319     {
17320       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17321         is_set = 1;
17322       else
17323         {
17324           clib_warning ("parse error '%U'", format_unformat_error, input);
17325           return -99;
17326         }
17327     }
17328
17329   if (!is_set)
17330     {
17331       errmsg ("Transport protocol missing!");
17332       return -99;
17333     }
17334
17335   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17336   mp->protocol = (u8) protocol;
17337
17338   /* send it... */
17339   S (mp);
17340
17341   /* Wait for a reply... */
17342   W (ret);
17343   return ret;
17344 }
17345
17346 static int
17347 api_one_get_transport_protocol (vat_main_t * vam)
17348 {
17349   vl_api_one_get_transport_protocol_t *mp;
17350   int ret;
17351
17352   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17353
17354   /* send it... */
17355   S (mp);
17356
17357   /* Wait for a reply... */
17358   W (ret);
17359   return ret;
17360 }
17361
17362 static int
17363 api_one_map_register_set_ttl (vat_main_t * vam)
17364 {
17365   unformat_input_t *input = vam->input;
17366   vl_api_one_map_register_set_ttl_t *mp;
17367   u32 ttl = 0;
17368   u8 is_set = 0;
17369   int ret;
17370
17371   /* Parse args required to build the message */
17372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17373     {
17374       if (unformat (input, "%u", &ttl))
17375         is_set = 1;
17376       else
17377         {
17378           clib_warning ("parse error '%U'", format_unformat_error, input);
17379           return -99;
17380         }
17381     }
17382
17383   if (!is_set)
17384     {
17385       errmsg ("TTL value missing!");
17386       return -99;
17387     }
17388
17389   M (ONE_MAP_REGISTER_SET_TTL, mp);
17390   mp->ttl = clib_host_to_net_u32 (ttl);
17391
17392   /* send it... */
17393   S (mp);
17394
17395   /* Wait for a reply... */
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static int
17401 api_show_one_map_register_ttl (vat_main_t * vam)
17402 {
17403   vl_api_show_one_map_register_ttl_t *mp;
17404   int ret;
17405
17406   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17407
17408   /* send it... */
17409   S (mp);
17410
17411   /* Wait for a reply... */
17412   W (ret);
17413   return ret;
17414 }
17415
17416 /**
17417  * Add/del map request itr rlocs from ONE control plane and updates
17418  *
17419  * @param vam vpp API test context
17420  * @return return code
17421  */
17422 static int
17423 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17424 {
17425   unformat_input_t *input = vam->input;
17426   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17427   u8 *locator_set_name = 0;
17428   u8 locator_set_name_set = 0;
17429   u8 is_add = 1;
17430   int ret;
17431
17432   /* Parse args required to build the message */
17433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17434     {
17435       if (unformat (input, "del"))
17436         {
17437           is_add = 0;
17438         }
17439       else if (unformat (input, "%_%v%_", &locator_set_name))
17440         {
17441           locator_set_name_set = 1;
17442         }
17443       else
17444         {
17445           clib_warning ("parse error '%U'", format_unformat_error, input);
17446           return -99;
17447         }
17448     }
17449
17450   if (is_add && !locator_set_name_set)
17451     {
17452       errmsg ("itr-rloc is not set!");
17453       return -99;
17454     }
17455
17456   if (is_add && vec_len (locator_set_name) > 64)
17457     {
17458       errmsg ("itr-rloc locator-set name too long");
17459       vec_free (locator_set_name);
17460       return -99;
17461     }
17462
17463   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17464   mp->is_add = is_add;
17465   if (is_add)
17466     {
17467       clib_memcpy (mp->locator_set_name, locator_set_name,
17468                    vec_len (locator_set_name));
17469     }
17470   else
17471     {
17472       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17473     }
17474   vec_free (locator_set_name);
17475
17476   /* send it... */
17477   S (mp);
17478
17479   /* Wait for a reply... */
17480   W (ret);
17481   return ret;
17482 }
17483
17484 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17485
17486 static int
17487 api_one_locator_dump (vat_main_t * vam)
17488 {
17489   unformat_input_t *input = vam->input;
17490   vl_api_one_locator_dump_t *mp;
17491   vl_api_control_ping_t *mp_ping;
17492   u8 is_index_set = 0, is_name_set = 0;
17493   u8 *ls_name = 0;
17494   u32 ls_index = ~0;
17495   int ret;
17496
17497   /* Parse args required to build the message */
17498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17499     {
17500       if (unformat (input, "ls_name %_%v%_", &ls_name))
17501         {
17502           is_name_set = 1;
17503         }
17504       else if (unformat (input, "ls_index %d", &ls_index))
17505         {
17506           is_index_set = 1;
17507         }
17508       else
17509         {
17510           errmsg ("parse error '%U'", format_unformat_error, input);
17511           return -99;
17512         }
17513     }
17514
17515   if (!is_index_set && !is_name_set)
17516     {
17517       errmsg ("error: expected one of index or name!");
17518       return -99;
17519     }
17520
17521   if (is_index_set && is_name_set)
17522     {
17523       errmsg ("error: only one param expected!");
17524       return -99;
17525     }
17526
17527   if (vec_len (ls_name) > 62)
17528     {
17529       errmsg ("error: locator set name too long!");
17530       return -99;
17531     }
17532
17533   if (!vam->json_output)
17534     {
17535       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17536     }
17537
17538   M (ONE_LOCATOR_DUMP, mp);
17539   mp->is_index_set = is_index_set;
17540
17541   if (is_index_set)
17542     mp->ls_index = clib_host_to_net_u32 (ls_index);
17543   else
17544     {
17545       vec_add1 (ls_name, 0);
17546       strncpy ((char *) mp->ls_name, (char *) ls_name,
17547                sizeof (mp->ls_name) - 1);
17548     }
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Use a control ping for synchronization */
17554   MPING (CONTROL_PING, mp_ping);
17555   S (mp_ping);
17556
17557   /* Wait for a reply... */
17558   W (ret);
17559   return ret;
17560 }
17561
17562 #define api_lisp_locator_dump api_one_locator_dump
17563
17564 static int
17565 api_one_locator_set_dump (vat_main_t * vam)
17566 {
17567   vl_api_one_locator_set_dump_t *mp;
17568   vl_api_control_ping_t *mp_ping;
17569   unformat_input_t *input = vam->input;
17570   u8 filter = 0;
17571   int ret;
17572
17573   /* Parse args required to build the message */
17574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17575     {
17576       if (unformat (input, "local"))
17577         {
17578           filter = 1;
17579         }
17580       else if (unformat (input, "remote"))
17581         {
17582           filter = 2;
17583         }
17584       else
17585         {
17586           errmsg ("parse error '%U'", format_unformat_error, input);
17587           return -99;
17588         }
17589     }
17590
17591   if (!vam->json_output)
17592     {
17593       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17594     }
17595
17596   M (ONE_LOCATOR_SET_DUMP, mp);
17597
17598   mp->filter = filter;
17599
17600   /* send it... */
17601   S (mp);
17602
17603   /* Use a control ping for synchronization */
17604   MPING (CONTROL_PING, mp_ping);
17605   S (mp_ping);
17606
17607   /* Wait for a reply... */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 #define api_lisp_locator_set_dump api_one_locator_set_dump
17613
17614 static int
17615 api_one_eid_table_map_dump (vat_main_t * vam)
17616 {
17617   u8 is_l2 = 0;
17618   u8 mode_set = 0;
17619   unformat_input_t *input = vam->input;
17620   vl_api_one_eid_table_map_dump_t *mp;
17621   vl_api_control_ping_t *mp_ping;
17622   int ret;
17623
17624   /* Parse args required to build the message */
17625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17626     {
17627       if (unformat (input, "l2"))
17628         {
17629           is_l2 = 1;
17630           mode_set = 1;
17631         }
17632       else if (unformat (input, "l3"))
17633         {
17634           is_l2 = 0;
17635           mode_set = 1;
17636         }
17637       else
17638         {
17639           errmsg ("parse error '%U'", format_unformat_error, input);
17640           return -99;
17641         }
17642     }
17643
17644   if (!mode_set)
17645     {
17646       errmsg ("expected one of 'l2' or 'l3' parameter!");
17647       return -99;
17648     }
17649
17650   if (!vam->json_output)
17651     {
17652       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17653     }
17654
17655   M (ONE_EID_TABLE_MAP_DUMP, mp);
17656   mp->is_l2 = is_l2;
17657
17658   /* send it... */
17659   S (mp);
17660
17661   /* Use a control ping for synchronization */
17662   MPING (CONTROL_PING, mp_ping);
17663   S (mp_ping);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17671
17672 static int
17673 api_one_eid_table_vni_dump (vat_main_t * vam)
17674 {
17675   vl_api_one_eid_table_vni_dump_t *mp;
17676   vl_api_control_ping_t *mp_ping;
17677   int ret;
17678
17679   if (!vam->json_output)
17680     {
17681       print (vam->ofp, "VNI");
17682     }
17683
17684   M (ONE_EID_TABLE_VNI_DUMP, mp);
17685
17686   /* send it... */
17687   S (mp);
17688
17689   /* Use a control ping for synchronization */
17690   MPING (CONTROL_PING, mp_ping);
17691   S (mp_ping);
17692
17693   /* Wait for a reply... */
17694   W (ret);
17695   return ret;
17696 }
17697
17698 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17699
17700 static int
17701 api_one_eid_table_dump (vat_main_t * vam)
17702 {
17703   unformat_input_t *i = vam->input;
17704   vl_api_one_eid_table_dump_t *mp;
17705   vl_api_control_ping_t *mp_ping;
17706   struct in_addr ip4;
17707   struct in6_addr ip6;
17708   u8 mac[6];
17709   u8 eid_type = ~0, eid_set = 0;
17710   u32 prefix_length = ~0, t, vni = 0;
17711   u8 filter = 0;
17712   int ret;
17713   lisp_nsh_api_t nsh;
17714
17715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17716     {
17717       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17718         {
17719           eid_set = 1;
17720           eid_type = 0;
17721           prefix_length = t;
17722         }
17723       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17724         {
17725           eid_set = 1;
17726           eid_type = 1;
17727           prefix_length = t;
17728         }
17729       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17730         {
17731           eid_set = 1;
17732           eid_type = 2;
17733         }
17734       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17735         {
17736           eid_set = 1;
17737           eid_type = 3;
17738         }
17739       else if (unformat (i, "vni %d", &t))
17740         {
17741           vni = t;
17742         }
17743       else if (unformat (i, "local"))
17744         {
17745           filter = 1;
17746         }
17747       else if (unformat (i, "remote"))
17748         {
17749           filter = 2;
17750         }
17751       else
17752         {
17753           errmsg ("parse error '%U'", format_unformat_error, i);
17754           return -99;
17755         }
17756     }
17757
17758   if (!vam->json_output)
17759     {
17760       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17761              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17762     }
17763
17764   M (ONE_EID_TABLE_DUMP, mp);
17765
17766   mp->filter = filter;
17767   if (eid_set)
17768     {
17769       mp->eid_set = 1;
17770       mp->vni = htonl (vni);
17771       mp->eid_type = eid_type;
17772       switch (eid_type)
17773         {
17774         case 0:
17775           mp->prefix_length = prefix_length;
17776           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17777           break;
17778         case 1:
17779           mp->prefix_length = prefix_length;
17780           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17781           break;
17782         case 2:
17783           clib_memcpy (mp->eid, mac, sizeof (mac));
17784           break;
17785         case 3:
17786           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17787           break;
17788         default:
17789           errmsg ("unknown EID type %d!", eid_type);
17790           return -99;
17791         }
17792     }
17793
17794   /* send it... */
17795   S (mp);
17796
17797   /* Use a control ping for synchronization */
17798   MPING (CONTROL_PING, mp_ping);
17799   S (mp_ping);
17800
17801   /* Wait for a reply... */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 #define api_lisp_eid_table_dump api_one_eid_table_dump
17807
17808 static int
17809 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17810 {
17811   unformat_input_t *i = vam->input;
17812   vl_api_gpe_fwd_entries_get_t *mp;
17813   u8 vni_set = 0;
17814   u32 vni = ~0;
17815   int ret;
17816
17817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (i, "vni %d", &vni))
17820         {
17821           vni_set = 1;
17822         }
17823       else
17824         {
17825           errmsg ("parse error '%U'", format_unformat_error, i);
17826           return -99;
17827         }
17828     }
17829
17830   if (!vni_set)
17831     {
17832       errmsg ("vni not set!");
17833       return -99;
17834     }
17835
17836   if (!vam->json_output)
17837     {
17838       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17839              "leid", "reid");
17840     }
17841
17842   M (GPE_FWD_ENTRIES_GET, mp);
17843   mp->vni = clib_host_to_net_u32 (vni);
17844
17845   /* send it... */
17846   S (mp);
17847
17848   /* Wait for a reply... */
17849   W (ret);
17850   return ret;
17851 }
17852
17853 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17854 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17855 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17856 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17857 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17858 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17859 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17860 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17861
17862 static int
17863 api_one_adjacencies_get (vat_main_t * vam)
17864 {
17865   unformat_input_t *i = vam->input;
17866   vl_api_one_adjacencies_get_t *mp;
17867   u8 vni_set = 0;
17868   u32 vni = ~0;
17869   int ret;
17870
17871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17872     {
17873       if (unformat (i, "vni %d", &vni))
17874         {
17875           vni_set = 1;
17876         }
17877       else
17878         {
17879           errmsg ("parse error '%U'", format_unformat_error, i);
17880           return -99;
17881         }
17882     }
17883
17884   if (!vni_set)
17885     {
17886       errmsg ("vni not set!");
17887       return -99;
17888     }
17889
17890   if (!vam->json_output)
17891     {
17892       print (vam->ofp, "%s %40s", "leid", "reid");
17893     }
17894
17895   M (ONE_ADJACENCIES_GET, mp);
17896   mp->vni = clib_host_to_net_u32 (vni);
17897
17898   /* send it... */
17899   S (mp);
17900
17901   /* Wait for a reply... */
17902   W (ret);
17903   return ret;
17904 }
17905
17906 #define api_lisp_adjacencies_get api_one_adjacencies_get
17907
17908 static int
17909 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17910 {
17911   unformat_input_t *i = vam->input;
17912   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17913   int ret;
17914   u8 ip_family_set = 0, is_ip4 = 1;
17915
17916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17917     {
17918       if (unformat (i, "ip4"))
17919         {
17920           ip_family_set = 1;
17921           is_ip4 = 1;
17922         }
17923       else if (unformat (i, "ip6"))
17924         {
17925           ip_family_set = 1;
17926           is_ip4 = 0;
17927         }
17928       else
17929         {
17930           errmsg ("parse error '%U'", format_unformat_error, i);
17931           return -99;
17932         }
17933     }
17934
17935   if (!ip_family_set)
17936     {
17937       errmsg ("ip family not set!");
17938       return -99;
17939     }
17940
17941   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17942   mp->is_ip4 = is_ip4;
17943
17944   /* send it... */
17945   S (mp);
17946
17947   /* Wait for a reply... */
17948   W (ret);
17949   return ret;
17950 }
17951
17952 static int
17953 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17954 {
17955   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17956   int ret;
17957
17958   if (!vam->json_output)
17959     {
17960       print (vam->ofp, "VNIs");
17961     }
17962
17963   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17964
17965   /* send it... */
17966   S (mp);
17967
17968   /* Wait for a reply... */
17969   W (ret);
17970   return ret;
17971 }
17972
17973 static int
17974 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17975 {
17976   unformat_input_t *i = vam->input;
17977   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17978   int ret = 0;
17979   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17980   struct in_addr ip4;
17981   struct in6_addr ip6;
17982   u32 table_id = 0, nh_sw_if_index = ~0;
17983
17984   clib_memset (&ip4, 0, sizeof (ip4));
17985   clib_memset (&ip6, 0, sizeof (ip6));
17986
17987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17988     {
17989       if (unformat (i, "del"))
17990         is_add = 0;
17991       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17992                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17993         {
17994           ip_set = 1;
17995           is_ip4 = 1;
17996         }
17997       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17998                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17999         {
18000           ip_set = 1;
18001           is_ip4 = 0;
18002         }
18003       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18004         {
18005           ip_set = 1;
18006           is_ip4 = 1;
18007           nh_sw_if_index = ~0;
18008         }
18009       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18010         {
18011           ip_set = 1;
18012           is_ip4 = 0;
18013           nh_sw_if_index = ~0;
18014         }
18015       else if (unformat (i, "table %d", &table_id))
18016         ;
18017       else
18018         {
18019           errmsg ("parse error '%U'", format_unformat_error, i);
18020           return -99;
18021         }
18022     }
18023
18024   if (!ip_set)
18025     {
18026       errmsg ("nh addr not set!");
18027       return -99;
18028     }
18029
18030   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18031   mp->is_add = is_add;
18032   mp->table_id = clib_host_to_net_u32 (table_id);
18033   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18034   mp->is_ip4 = is_ip4;
18035   if (is_ip4)
18036     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18037   else
18038     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18039
18040   /* send it... */
18041   S (mp);
18042
18043   /* Wait for a reply... */
18044   W (ret);
18045   return ret;
18046 }
18047
18048 static int
18049 api_one_map_server_dump (vat_main_t * vam)
18050 {
18051   vl_api_one_map_server_dump_t *mp;
18052   vl_api_control_ping_t *mp_ping;
18053   int ret;
18054
18055   if (!vam->json_output)
18056     {
18057       print (vam->ofp, "%=20s", "Map server");
18058     }
18059
18060   M (ONE_MAP_SERVER_DUMP, mp);
18061   /* send it... */
18062   S (mp);
18063
18064   /* Use a control ping for synchronization */
18065   MPING (CONTROL_PING, mp_ping);
18066   S (mp_ping);
18067
18068   /* Wait for a reply... */
18069   W (ret);
18070   return ret;
18071 }
18072
18073 #define api_lisp_map_server_dump api_one_map_server_dump
18074
18075 static int
18076 api_one_map_resolver_dump (vat_main_t * vam)
18077 {
18078   vl_api_one_map_resolver_dump_t *mp;
18079   vl_api_control_ping_t *mp_ping;
18080   int ret;
18081
18082   if (!vam->json_output)
18083     {
18084       print (vam->ofp, "%=20s", "Map resolver");
18085     }
18086
18087   M (ONE_MAP_RESOLVER_DUMP, mp);
18088   /* send it... */
18089   S (mp);
18090
18091   /* Use a control ping for synchronization */
18092   MPING (CONTROL_PING, mp_ping);
18093   S (mp_ping);
18094
18095   /* Wait for a reply... */
18096   W (ret);
18097   return ret;
18098 }
18099
18100 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18101
18102 static int
18103 api_one_stats_flush (vat_main_t * vam)
18104 {
18105   vl_api_one_stats_flush_t *mp;
18106   int ret = 0;
18107
18108   M (ONE_STATS_FLUSH, mp);
18109   S (mp);
18110   W (ret);
18111   return ret;
18112 }
18113
18114 static int
18115 api_one_stats_dump (vat_main_t * vam)
18116 {
18117   vl_api_one_stats_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   int ret;
18120
18121   M (ONE_STATS_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 static int
18135 api_show_one_status (vat_main_t * vam)
18136 {
18137   vl_api_show_one_status_t *mp;
18138   int ret;
18139
18140   if (!vam->json_output)
18141     {
18142       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18143     }
18144
18145   M (SHOW_ONE_STATUS, mp);
18146   /* send it... */
18147   S (mp);
18148   /* Wait for a reply... */
18149   W (ret);
18150   return ret;
18151 }
18152
18153 #define api_show_lisp_status api_show_one_status
18154
18155 static int
18156 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18157 {
18158   vl_api_gpe_fwd_entry_path_dump_t *mp;
18159   vl_api_control_ping_t *mp_ping;
18160   unformat_input_t *i = vam->input;
18161   u32 fwd_entry_index = ~0;
18162   int ret;
18163
18164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (i, "index %d", &fwd_entry_index))
18167         ;
18168       else
18169         break;
18170     }
18171
18172   if (~0 == fwd_entry_index)
18173     {
18174       errmsg ("no index specified!");
18175       return -99;
18176     }
18177
18178   if (!vam->json_output)
18179     {
18180       print (vam->ofp, "first line");
18181     }
18182
18183   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18184
18185   /* send it... */
18186   S (mp);
18187   /* Use a control ping for synchronization */
18188   MPING (CONTROL_PING, mp_ping);
18189   S (mp_ping);
18190
18191   /* Wait for a reply... */
18192   W (ret);
18193   return ret;
18194 }
18195
18196 static int
18197 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18198 {
18199   vl_api_one_get_map_request_itr_rlocs_t *mp;
18200   int ret;
18201
18202   if (!vam->json_output)
18203     {
18204       print (vam->ofp, "%=20s", "itr-rlocs:");
18205     }
18206
18207   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18208   /* send it... */
18209   S (mp);
18210   /* Wait for a reply... */
18211   W (ret);
18212   return ret;
18213 }
18214
18215 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18216
18217 static int
18218 api_af_packet_create (vat_main_t * vam)
18219 {
18220   unformat_input_t *i = vam->input;
18221   vl_api_af_packet_create_t *mp;
18222   u8 *host_if_name = 0;
18223   u8 hw_addr[6];
18224   u8 random_hw_addr = 1;
18225   int ret;
18226
18227   clib_memset (hw_addr, 0, sizeof (hw_addr));
18228
18229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18230     {
18231       if (unformat (i, "name %s", &host_if_name))
18232         vec_add1 (host_if_name, 0);
18233       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18234         random_hw_addr = 0;
18235       else
18236         break;
18237     }
18238
18239   if (!vec_len (host_if_name))
18240     {
18241       errmsg ("host-interface name must be specified");
18242       return -99;
18243     }
18244
18245   if (vec_len (host_if_name) > 64)
18246     {
18247       errmsg ("host-interface name too long");
18248       return -99;
18249     }
18250
18251   M (AF_PACKET_CREATE, mp);
18252
18253   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18254   clib_memcpy (mp->hw_addr, hw_addr, 6);
18255   mp->use_random_hw_addr = random_hw_addr;
18256   vec_free (host_if_name);
18257
18258   S (mp);
18259
18260   /* *INDENT-OFF* */
18261   W2 (ret,
18262       ({
18263         if (ret == 0)
18264           fprintf (vam->ofp ? vam->ofp : stderr,
18265                    " new sw_if_index = %d\n", vam->sw_if_index);
18266       }));
18267   /* *INDENT-ON* */
18268   return ret;
18269 }
18270
18271 static int
18272 api_af_packet_delete (vat_main_t * vam)
18273 {
18274   unformat_input_t *i = vam->input;
18275   vl_api_af_packet_delete_t *mp;
18276   u8 *host_if_name = 0;
18277   int ret;
18278
18279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18280     {
18281       if (unformat (i, "name %s", &host_if_name))
18282         vec_add1 (host_if_name, 0);
18283       else
18284         break;
18285     }
18286
18287   if (!vec_len (host_if_name))
18288     {
18289       errmsg ("host-interface name must be specified");
18290       return -99;
18291     }
18292
18293   if (vec_len (host_if_name) > 64)
18294     {
18295       errmsg ("host-interface name too long");
18296       return -99;
18297     }
18298
18299   M (AF_PACKET_DELETE, mp);
18300
18301   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18302   vec_free (host_if_name);
18303
18304   S (mp);
18305   W (ret);
18306   return ret;
18307 }
18308
18309 static void vl_api_af_packet_details_t_handler
18310   (vl_api_af_packet_details_t * mp)
18311 {
18312   vat_main_t *vam = &vat_main;
18313
18314   print (vam->ofp, "%-16s %d",
18315          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18316 }
18317
18318 static void vl_api_af_packet_details_t_handler_json
18319   (vl_api_af_packet_details_t * mp)
18320 {
18321   vat_main_t *vam = &vat_main;
18322   vat_json_node_t *node = NULL;
18323
18324   if (VAT_JSON_ARRAY != vam->json_tree.type)
18325     {
18326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18327       vat_json_init_array (&vam->json_tree);
18328     }
18329   node = vat_json_array_add (&vam->json_tree);
18330
18331   vat_json_init_object (node);
18332   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18333   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18334 }
18335
18336 static int
18337 api_af_packet_dump (vat_main_t * vam)
18338 {
18339   vl_api_af_packet_dump_t *mp;
18340   vl_api_control_ping_t *mp_ping;
18341   int ret;
18342
18343   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18344   /* Get list of tap interfaces */
18345   M (AF_PACKET_DUMP, mp);
18346   S (mp);
18347
18348   /* Use a control ping for synchronization */
18349   MPING (CONTROL_PING, mp_ping);
18350   S (mp_ping);
18351
18352   W (ret);
18353   return ret;
18354 }
18355
18356 static int
18357 api_policer_add_del (vat_main_t * vam)
18358 {
18359   unformat_input_t *i = vam->input;
18360   vl_api_policer_add_del_t *mp;
18361   u8 is_add = 1;
18362   u8 *name = 0;
18363   u32 cir = 0;
18364   u32 eir = 0;
18365   u64 cb = 0;
18366   u64 eb = 0;
18367   u8 rate_type = 0;
18368   u8 round_type = 0;
18369   u8 type = 0;
18370   u8 color_aware = 0;
18371   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18372   int ret;
18373
18374   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18375   conform_action.dscp = 0;
18376   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18377   exceed_action.dscp = 0;
18378   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18379   violate_action.dscp = 0;
18380
18381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18382     {
18383       if (unformat (i, "del"))
18384         is_add = 0;
18385       else if (unformat (i, "name %s", &name))
18386         vec_add1 (name, 0);
18387       else if (unformat (i, "cir %u", &cir))
18388         ;
18389       else if (unformat (i, "eir %u", &eir))
18390         ;
18391       else if (unformat (i, "cb %u", &cb))
18392         ;
18393       else if (unformat (i, "eb %u", &eb))
18394         ;
18395       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18396                          &rate_type))
18397         ;
18398       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18399                          &round_type))
18400         ;
18401       else if (unformat (i, "type %U", unformat_policer_type, &type))
18402         ;
18403       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18404                          &conform_action))
18405         ;
18406       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18407                          &exceed_action))
18408         ;
18409       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18410                          &violate_action))
18411         ;
18412       else if (unformat (i, "color-aware"))
18413         color_aware = 1;
18414       else
18415         break;
18416     }
18417
18418   if (!vec_len (name))
18419     {
18420       errmsg ("policer name must be specified");
18421       return -99;
18422     }
18423
18424   if (vec_len (name) > 64)
18425     {
18426       errmsg ("policer name too long");
18427       return -99;
18428     }
18429
18430   M (POLICER_ADD_DEL, mp);
18431
18432   clib_memcpy (mp->name, name, vec_len (name));
18433   vec_free (name);
18434   mp->is_add = is_add;
18435   mp->cir = ntohl (cir);
18436   mp->eir = ntohl (eir);
18437   mp->cb = clib_net_to_host_u64 (cb);
18438   mp->eb = clib_net_to_host_u64 (eb);
18439   mp->rate_type = rate_type;
18440   mp->round_type = round_type;
18441   mp->type = type;
18442   mp->conform_action_type = conform_action.action_type;
18443   mp->conform_dscp = conform_action.dscp;
18444   mp->exceed_action_type = exceed_action.action_type;
18445   mp->exceed_dscp = exceed_action.dscp;
18446   mp->violate_action_type = violate_action.action_type;
18447   mp->violate_dscp = violate_action.dscp;
18448   mp->color_aware = color_aware;
18449
18450   S (mp);
18451   W (ret);
18452   return ret;
18453 }
18454
18455 static int
18456 api_policer_dump (vat_main_t * vam)
18457 {
18458   unformat_input_t *i = vam->input;
18459   vl_api_policer_dump_t *mp;
18460   vl_api_control_ping_t *mp_ping;
18461   u8 *match_name = 0;
18462   u8 match_name_valid = 0;
18463   int ret;
18464
18465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18466     {
18467       if (unformat (i, "name %s", &match_name))
18468         {
18469           vec_add1 (match_name, 0);
18470           match_name_valid = 1;
18471         }
18472       else
18473         break;
18474     }
18475
18476   M (POLICER_DUMP, mp);
18477   mp->match_name_valid = match_name_valid;
18478   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18479   vec_free (match_name);
18480   /* send it... */
18481   S (mp);
18482
18483   /* Use a control ping for synchronization */
18484   MPING (CONTROL_PING, mp_ping);
18485   S (mp_ping);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 static int
18493 api_policer_classify_set_interface (vat_main_t * vam)
18494 {
18495   unformat_input_t *i = vam->input;
18496   vl_api_policer_classify_set_interface_t *mp;
18497   u32 sw_if_index;
18498   int sw_if_index_set;
18499   u32 ip4_table_index = ~0;
18500   u32 ip6_table_index = ~0;
18501   u32 l2_table_index = ~0;
18502   u8 is_add = 1;
18503   int ret;
18504
18505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18506     {
18507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18508         sw_if_index_set = 1;
18509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18510         sw_if_index_set = 1;
18511       else if (unformat (i, "del"))
18512         is_add = 0;
18513       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18514         ;
18515       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18516         ;
18517       else if (unformat (i, "l2-table %d", &l2_table_index))
18518         ;
18519       else
18520         {
18521           clib_warning ("parse error '%U'", format_unformat_error, i);
18522           return -99;
18523         }
18524     }
18525
18526   if (sw_if_index_set == 0)
18527     {
18528       errmsg ("missing interface name or sw_if_index");
18529       return -99;
18530     }
18531
18532   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18533
18534   mp->sw_if_index = ntohl (sw_if_index);
18535   mp->ip4_table_index = ntohl (ip4_table_index);
18536   mp->ip6_table_index = ntohl (ip6_table_index);
18537   mp->l2_table_index = ntohl (l2_table_index);
18538   mp->is_add = is_add;
18539
18540   S (mp);
18541   W (ret);
18542   return ret;
18543 }
18544
18545 static int
18546 api_policer_classify_dump (vat_main_t * vam)
18547 {
18548   unformat_input_t *i = vam->input;
18549   vl_api_policer_classify_dump_t *mp;
18550   vl_api_control_ping_t *mp_ping;
18551   u8 type = POLICER_CLASSIFY_N_TABLES;
18552   int ret;
18553
18554   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18555     ;
18556   else
18557     {
18558       errmsg ("classify table type must be specified");
18559       return -99;
18560     }
18561
18562   if (!vam->json_output)
18563     {
18564       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18565     }
18566
18567   M (POLICER_CLASSIFY_DUMP, mp);
18568   mp->type = type;
18569   /* send it... */
18570   S (mp);
18571
18572   /* Use a control ping for synchronization */
18573   MPING (CONTROL_PING, mp_ping);
18574   S (mp_ping);
18575
18576   /* Wait for a reply... */
18577   W (ret);
18578   return ret;
18579 }
18580
18581 static int
18582 api_netmap_create (vat_main_t * vam)
18583 {
18584   unformat_input_t *i = vam->input;
18585   vl_api_netmap_create_t *mp;
18586   u8 *if_name = 0;
18587   u8 hw_addr[6];
18588   u8 random_hw_addr = 1;
18589   u8 is_pipe = 0;
18590   u8 is_master = 0;
18591   int ret;
18592
18593   clib_memset (hw_addr, 0, sizeof (hw_addr));
18594
18595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18596     {
18597       if (unformat (i, "name %s", &if_name))
18598         vec_add1 (if_name, 0);
18599       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18600         random_hw_addr = 0;
18601       else if (unformat (i, "pipe"))
18602         is_pipe = 1;
18603       else if (unformat (i, "master"))
18604         is_master = 1;
18605       else if (unformat (i, "slave"))
18606         is_master = 0;
18607       else
18608         break;
18609     }
18610
18611   if (!vec_len (if_name))
18612     {
18613       errmsg ("interface name must be specified");
18614       return -99;
18615     }
18616
18617   if (vec_len (if_name) > 64)
18618     {
18619       errmsg ("interface name too long");
18620       return -99;
18621     }
18622
18623   M (NETMAP_CREATE, mp);
18624
18625   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18626   clib_memcpy (mp->hw_addr, hw_addr, 6);
18627   mp->use_random_hw_addr = random_hw_addr;
18628   mp->is_pipe = is_pipe;
18629   mp->is_master = is_master;
18630   vec_free (if_name);
18631
18632   S (mp);
18633   W (ret);
18634   return ret;
18635 }
18636
18637 static int
18638 api_netmap_delete (vat_main_t * vam)
18639 {
18640   unformat_input_t *i = vam->input;
18641   vl_api_netmap_delete_t *mp;
18642   u8 *if_name = 0;
18643   int ret;
18644
18645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18646     {
18647       if (unformat (i, "name %s", &if_name))
18648         vec_add1 (if_name, 0);
18649       else
18650         break;
18651     }
18652
18653   if (!vec_len (if_name))
18654     {
18655       errmsg ("interface name must be specified");
18656       return -99;
18657     }
18658
18659   if (vec_len (if_name) > 64)
18660     {
18661       errmsg ("interface name too long");
18662       return -99;
18663     }
18664
18665   M (NETMAP_DELETE, mp);
18666
18667   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18668   vec_free (if_name);
18669
18670   S (mp);
18671   W (ret);
18672   return ret;
18673 }
18674
18675 static u8 *
18676 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18677 {
18678   vl_api_fib_path_nh_proto_t proto =
18679     va_arg (*args, vl_api_fib_path_nh_proto_t);
18680
18681   switch (proto)
18682     {
18683     case FIB_API_PATH_NH_PROTO_IP4:
18684       s = format (s, "ip4");
18685       break;
18686     case FIB_API_PATH_NH_PROTO_IP6:
18687       s = format (s, "ip6");
18688       break;
18689     case FIB_API_PATH_NH_PROTO_MPLS:
18690       s = format (s, "mpls");
18691       break;
18692     case FIB_API_PATH_NH_PROTO_BIER:
18693       s = format (s, "bier");
18694       break;
18695     case FIB_API_PATH_NH_PROTO_ETHERNET:
18696       s = format (s, "ethernet");
18697       break;
18698     }
18699
18700   return (s);
18701 }
18702
18703 static u8 *
18704 format_vl_api_ip_address_union (u8 * s, va_list * args)
18705 {
18706   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18707   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18708
18709   switch (af)
18710     {
18711     case ADDRESS_IP4:
18712       s = format (s, "%U", format_ip4_address, u->ip4);
18713       break;
18714     case ADDRESS_IP6:
18715       s = format (s, "%U", format_ip6_address, u->ip6);
18716       break;
18717     }
18718   return (s);
18719 }
18720
18721 static u8 *
18722 format_vl_api_fib_path_type (u8 * s, va_list * args)
18723 {
18724   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18725
18726   switch (t)
18727     {
18728     case FIB_API_PATH_TYPE_NORMAL:
18729       s = format (s, "normal");
18730       break;
18731     case FIB_API_PATH_TYPE_LOCAL:
18732       s = format (s, "local");
18733       break;
18734     case FIB_API_PATH_TYPE_DROP:
18735       s = format (s, "drop");
18736       break;
18737     case FIB_API_PATH_TYPE_UDP_ENCAP:
18738       s = format (s, "udp-encap");
18739       break;
18740     case FIB_API_PATH_TYPE_BIER_IMP:
18741       s = format (s, "bier-imp");
18742       break;
18743     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18744       s = format (s, "unreach");
18745       break;
18746     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18747       s = format (s, "prohibit");
18748       break;
18749     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18750       s = format (s, "src-lookup");
18751       break;
18752     case FIB_API_PATH_TYPE_DVR:
18753       s = format (s, "dvr");
18754       break;
18755     case FIB_API_PATH_TYPE_INTERFACE_RX:
18756       s = format (s, "interface-rx");
18757       break;
18758     case FIB_API_PATH_TYPE_CLASSIFY:
18759       s = format (s, "classify");
18760       break;
18761     }
18762
18763   return (s);
18764 }
18765
18766 static void
18767 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18768 {
18769   print (vam->ofp,
18770          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18771          ntohl (fp->weight), ntohl (fp->sw_if_index),
18772          format_vl_api_fib_path_type, fp->type,
18773          format_fib_api_path_nh_proto, fp->proto,
18774          format_vl_api_ip_address_union, &fp->nh.address);
18775 }
18776
18777 static void
18778 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18779                                  vl_api_fib_path_t * fp)
18780 {
18781   struct in_addr ip4;
18782   struct in6_addr ip6;
18783
18784   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18785   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18786   vat_json_object_add_uint (node, "type", fp->type);
18787   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18788   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18789     {
18790       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18791       vat_json_object_add_ip4 (node, "next_hop", ip4);
18792     }
18793   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18794     {
18795       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18796       vat_json_object_add_ip6 (node, "next_hop", ip6);
18797     }
18798 }
18799
18800 static void
18801 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18802 {
18803   vat_main_t *vam = &vat_main;
18804   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18805   vl_api_fib_path_t *fp;
18806   i32 i;
18807
18808   print (vam->ofp, "sw_if_index %d via:",
18809          ntohl (mp->mt_tunnel.mt_sw_if_index));
18810   fp = mp->mt_tunnel.mt_paths;
18811   for (i = 0; i < count; i++)
18812     {
18813       vl_api_fib_path_print (vam, fp);
18814       fp++;
18815     }
18816
18817   print (vam->ofp, "");
18818 }
18819
18820 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18821 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18822
18823 static void
18824 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18825 {
18826   vat_main_t *vam = &vat_main;
18827   vat_json_node_t *node = NULL;
18828   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18829   vl_api_fib_path_t *fp;
18830   i32 i;
18831
18832   if (VAT_JSON_ARRAY != vam->json_tree.type)
18833     {
18834       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18835       vat_json_init_array (&vam->json_tree);
18836     }
18837   node = vat_json_array_add (&vam->json_tree);
18838
18839   vat_json_init_object (node);
18840   vat_json_object_add_uint (node, "sw_if_index",
18841                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18842
18843   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18844
18845   fp = mp->mt_tunnel.mt_paths;
18846   for (i = 0; i < count; i++)
18847     {
18848       vl_api_mpls_fib_path_json_print (node, fp);
18849       fp++;
18850     }
18851 }
18852
18853 static int
18854 api_mpls_tunnel_dump (vat_main_t * vam)
18855 {
18856   vl_api_mpls_tunnel_dump_t *mp;
18857   vl_api_control_ping_t *mp_ping;
18858   int ret;
18859
18860   M (MPLS_TUNNEL_DUMP, mp);
18861
18862   S (mp);
18863
18864   /* Use a control ping for synchronization */
18865   MPING (CONTROL_PING, mp_ping);
18866   S (mp_ping);
18867
18868   W (ret);
18869   return ret;
18870 }
18871
18872 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18873 #define vl_api_mpls_table_details_t_print vl_noop_handler
18874
18875
18876 static void
18877 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18878 {
18879   vat_main_t *vam = &vat_main;
18880
18881   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18882 }
18883
18884 static void vl_api_mpls_table_details_t_handler_json
18885   (vl_api_mpls_table_details_t * mp)
18886 {
18887   vat_main_t *vam = &vat_main;
18888   vat_json_node_t *node = NULL;
18889
18890   if (VAT_JSON_ARRAY != vam->json_tree.type)
18891     {
18892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18893       vat_json_init_array (&vam->json_tree);
18894     }
18895   node = vat_json_array_add (&vam->json_tree);
18896
18897   vat_json_init_object (node);
18898   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18899 }
18900
18901 static int
18902 api_mpls_table_dump (vat_main_t * vam)
18903 {
18904   vl_api_mpls_table_dump_t *mp;
18905   vl_api_control_ping_t *mp_ping;
18906   int ret;
18907
18908   M (MPLS_TABLE_DUMP, mp);
18909   S (mp);
18910
18911   /* Use a control ping for synchronization */
18912   MPING (CONTROL_PING, mp_ping);
18913   S (mp_ping);
18914
18915   W (ret);
18916   return ret;
18917 }
18918
18919 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18920 #define vl_api_mpls_route_details_t_print vl_noop_handler
18921
18922 static void
18923 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18924 {
18925   vat_main_t *vam = &vat_main;
18926   int count = ntohl (mp->mr_route.mr_n_paths);
18927   vl_api_fib_path_t *fp;
18928   int i;
18929
18930   print (vam->ofp,
18931          "table-id %d, label %u, ess_bit %u",
18932          ntohl (mp->mr_route.mr_table_id),
18933          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18934   fp = mp->mr_route.mr_paths;
18935   for (i = 0; i < count; i++)
18936     {
18937       vl_api_fib_path_print (vam, fp);
18938       fp++;
18939     }
18940 }
18941
18942 static void vl_api_mpls_route_details_t_handler_json
18943   (vl_api_mpls_route_details_t * mp)
18944 {
18945   vat_main_t *vam = &vat_main;
18946   int count = ntohl (mp->mr_route.mr_n_paths);
18947   vat_json_node_t *node = NULL;
18948   vl_api_fib_path_t *fp;
18949   int i;
18950
18951   if (VAT_JSON_ARRAY != vam->json_tree.type)
18952     {
18953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18954       vat_json_init_array (&vam->json_tree);
18955     }
18956   node = vat_json_array_add (&vam->json_tree);
18957
18958   vat_json_init_object (node);
18959   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18960   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18961   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18962   vat_json_object_add_uint (node, "path_count", count);
18963   fp = mp->mr_route.mr_paths;
18964   for (i = 0; i < count; i++)
18965     {
18966       vl_api_mpls_fib_path_json_print (node, fp);
18967       fp++;
18968     }
18969 }
18970
18971 static int
18972 api_mpls_route_dump (vat_main_t * vam)
18973 {
18974   unformat_input_t *input = vam->input;
18975   vl_api_mpls_route_dump_t *mp;
18976   vl_api_control_ping_t *mp_ping;
18977   u32 table_id;
18978   int ret;
18979
18980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18981     {
18982       if (unformat (input, "table_id %d", &table_id))
18983         ;
18984       else
18985         break;
18986     }
18987   if (table_id == ~0)
18988     {
18989       errmsg ("missing table id");
18990       return -99;
18991     }
18992
18993   M (MPLS_ROUTE_DUMP, mp);
18994
18995   mp->table.mt_table_id = ntohl (table_id);
18996   S (mp);
18997
18998   /* Use a control ping for synchronization */
18999   MPING (CONTROL_PING, mp_ping);
19000   S (mp_ping);
19001
19002   W (ret);
19003   return ret;
19004 }
19005
19006 #define vl_api_ip_table_details_t_endian vl_noop_handler
19007 #define vl_api_ip_table_details_t_print vl_noop_handler
19008
19009 static void
19010 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19011 {
19012   vat_main_t *vam = &vat_main;
19013
19014   print (vam->ofp,
19015          "%s; table-id %d, prefix %U/%d",
19016          mp->table.name, ntohl (mp->table.table_id));
19017 }
19018
19019
19020 static void vl_api_ip_table_details_t_handler_json
19021   (vl_api_ip_table_details_t * mp)
19022 {
19023   vat_main_t *vam = &vat_main;
19024   vat_json_node_t *node = NULL;
19025
19026   if (VAT_JSON_ARRAY != vam->json_tree.type)
19027     {
19028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19029       vat_json_init_array (&vam->json_tree);
19030     }
19031   node = vat_json_array_add (&vam->json_tree);
19032
19033   vat_json_init_object (node);
19034   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19035 }
19036
19037 static int
19038 api_ip_table_dump (vat_main_t * vam)
19039 {
19040   vl_api_ip_table_dump_t *mp;
19041   vl_api_control_ping_t *mp_ping;
19042   int ret;
19043
19044   M (IP_TABLE_DUMP, mp);
19045   S (mp);
19046
19047   /* Use a control ping for synchronization */
19048   MPING (CONTROL_PING, mp_ping);
19049   S (mp_ping);
19050
19051   W (ret);
19052   return ret;
19053 }
19054
19055 static int
19056 api_ip_mtable_dump (vat_main_t * vam)
19057 {
19058   vl_api_ip_mtable_dump_t *mp;
19059   vl_api_control_ping_t *mp_ping;
19060   int ret;
19061
19062   M (IP_MTABLE_DUMP, mp);
19063   S (mp);
19064
19065   /* Use a control ping for synchronization */
19066   MPING (CONTROL_PING, mp_ping);
19067   S (mp_ping);
19068
19069   W (ret);
19070   return ret;
19071 }
19072
19073 static int
19074 api_ip_mroute_dump (vat_main_t * vam)
19075 {
19076   unformat_input_t *input = vam->input;
19077   vl_api_control_ping_t *mp_ping;
19078   vl_api_ip_mroute_dump_t *mp;
19079   int ret, is_ip6;
19080   u32 table_id;
19081
19082   is_ip6 = 0;
19083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19084     {
19085       if (unformat (input, "table_id %d", &table_id))
19086         ;
19087       else if (unformat (input, "ip6"))
19088         is_ip6 = 1;
19089       else if (unformat (input, "ip4"))
19090         is_ip6 = 0;
19091       else
19092         break;
19093     }
19094   if (table_id == ~0)
19095     {
19096       errmsg ("missing table id");
19097       return -99;
19098     }
19099
19100   M (IP_MROUTE_DUMP, mp);
19101   mp->table.table_id = table_id;
19102   mp->table.is_ip6 = is_ip6;
19103   S (mp);
19104
19105   /* Use a control ping for synchronization */
19106   MPING (CONTROL_PING, mp_ping);
19107   S (mp_ping);
19108
19109   W (ret);
19110   return ret;
19111 }
19112
19113 static void vl_api_ip_neighbor_details_t_handler
19114   (vl_api_ip_neighbor_details_t * mp)
19115 {
19116   vat_main_t *vam = &vat_main;
19117
19118   print (vam->ofp, "%c %U %U",
19119          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19120          format_vl_api_mac_address, &mp->neighbor.mac_address,
19121          format_vl_api_address, &mp->neighbor.ip_address);
19122 }
19123
19124 static void vl_api_ip_neighbor_details_t_handler_json
19125   (vl_api_ip_neighbor_details_t * mp)
19126 {
19127
19128   vat_main_t *vam = &vat_main;
19129   vat_json_node_t *node;
19130
19131   if (VAT_JSON_ARRAY != vam->json_tree.type)
19132     {
19133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19134       vat_json_init_array (&vam->json_tree);
19135     }
19136   node = vat_json_array_add (&vam->json_tree);
19137
19138   vat_json_init_object (node);
19139   vat_json_object_add_string_copy
19140     (node, "flag",
19141      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19142       (u8 *) "static" : (u8 *) "dynamic"));
19143
19144   vat_json_object_add_string_copy (node, "link_layer",
19145                                    format (0, "%U", format_vl_api_mac_address,
19146                                            &mp->neighbor.mac_address));
19147   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19148 }
19149
19150 static int
19151 api_ip_neighbor_dump (vat_main_t * vam)
19152 {
19153   unformat_input_t *i = vam->input;
19154   vl_api_ip_neighbor_dump_t *mp;
19155   vl_api_control_ping_t *mp_ping;
19156   u8 is_ipv6 = 0;
19157   u32 sw_if_index = ~0;
19158   int ret;
19159
19160   /* Parse args required to build the message */
19161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19162     {
19163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19164         ;
19165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19166         ;
19167       else if (unformat (i, "ip6"))
19168         is_ipv6 = 1;
19169       else
19170         break;
19171     }
19172
19173   if (sw_if_index == ~0)
19174     {
19175       errmsg ("missing interface name or sw_if_index");
19176       return -99;
19177     }
19178
19179   M (IP_NEIGHBOR_DUMP, mp);
19180   mp->is_ipv6 = (u8) is_ipv6;
19181   mp->sw_if_index = ntohl (sw_if_index);
19182   S (mp);
19183
19184   /* Use a control ping for synchronization */
19185   MPING (CONTROL_PING, mp_ping);
19186   S (mp_ping);
19187
19188   W (ret);
19189   return ret;
19190 }
19191
19192 #define vl_api_ip_route_details_t_endian vl_noop_handler
19193 #define vl_api_ip_route_details_t_print vl_noop_handler
19194
19195 static void
19196 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19197 {
19198   vat_main_t *vam = &vat_main;
19199   u8 count = mp->route.n_paths;
19200   vl_api_fib_path_t *fp;
19201   int i;
19202
19203   print (vam->ofp,
19204          "table-id %d, prefix %U/%d",
19205          ntohl (mp->route.table_id),
19206          format_ip46_address,
19207          mp->route.prefix.address, mp->route.prefix.address_length);
19208   for (i = 0; i < count; i++)
19209     {
19210       fp = &mp->route.paths[i];
19211
19212       vl_api_fib_path_print (vam, fp);
19213       fp++;
19214     }
19215 }
19216
19217 static void vl_api_ip_route_details_t_handler_json
19218   (vl_api_ip_route_details_t * mp)
19219 {
19220   vat_main_t *vam = &vat_main;
19221   u8 count = mp->route.n_paths;
19222   vat_json_node_t *node = NULL;
19223   struct in_addr ip4;
19224   struct in6_addr ip6;
19225   vl_api_fib_path_t *fp;
19226   int i;
19227
19228   if (VAT_JSON_ARRAY != vam->json_tree.type)
19229     {
19230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19231       vat_json_init_array (&vam->json_tree);
19232     }
19233   node = vat_json_array_add (&vam->json_tree);
19234
19235   vat_json_init_object (node);
19236   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19237   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19238     {
19239       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19240       vat_json_object_add_ip6 (node, "prefix", ip6);
19241     }
19242   else
19243     {
19244       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19245       vat_json_object_add_ip4 (node, "prefix", ip4);
19246     }
19247   vat_json_object_add_uint (node, "mask_length",
19248                             mp->route.prefix.address_length);
19249   vat_json_object_add_uint (node, "path_count", count);
19250   for (i = 0; i < count; i++)
19251     {
19252       fp = &mp->route.paths[i];
19253       vl_api_mpls_fib_path_json_print (node, fp);
19254     }
19255 }
19256
19257 static int
19258 api_ip_route_dump (vat_main_t * vam)
19259 {
19260   unformat_input_t *input = vam->input;
19261   vl_api_ip_route_dump_t *mp;
19262   vl_api_control_ping_t *mp_ping;
19263   u32 table_id;
19264   u8 is_ip6;
19265   int ret;
19266
19267   is_ip6 = 0;
19268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19269     {
19270       if (unformat (input, "table_id %d", &table_id))
19271         ;
19272       else if (unformat (input, "ip6"))
19273         is_ip6 = 1;
19274       else if (unformat (input, "ip4"))
19275         is_ip6 = 0;
19276       else
19277         break;
19278     }
19279   if (table_id == ~0)
19280     {
19281       errmsg ("missing table id");
19282       return -99;
19283     }
19284
19285   M (IP_ROUTE_DUMP, mp);
19286
19287   mp->table.table_id = table_id;
19288   mp->table.is_ip6 = is_ip6;
19289
19290   S (mp);
19291
19292   /* Use a control ping for synchronization */
19293   MPING (CONTROL_PING, mp_ping);
19294   S (mp_ping);
19295
19296   W (ret);
19297   return ret;
19298 }
19299
19300 int
19301 api_classify_table_ids (vat_main_t * vam)
19302 {
19303   vl_api_classify_table_ids_t *mp;
19304   int ret;
19305
19306   /* Construct the API message */
19307   M (CLASSIFY_TABLE_IDS, mp);
19308   mp->context = 0;
19309
19310   S (mp);
19311   W (ret);
19312   return ret;
19313 }
19314
19315 int
19316 api_classify_table_by_interface (vat_main_t * vam)
19317 {
19318   unformat_input_t *input = vam->input;
19319   vl_api_classify_table_by_interface_t *mp;
19320
19321   u32 sw_if_index = ~0;
19322   int ret;
19323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19324     {
19325       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19326         ;
19327       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19328         ;
19329       else
19330         break;
19331     }
19332   if (sw_if_index == ~0)
19333     {
19334       errmsg ("missing interface name or sw_if_index");
19335       return -99;
19336     }
19337
19338   /* Construct the API message */
19339   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19340   mp->context = 0;
19341   mp->sw_if_index = ntohl (sw_if_index);
19342
19343   S (mp);
19344   W (ret);
19345   return ret;
19346 }
19347
19348 int
19349 api_classify_table_info (vat_main_t * vam)
19350 {
19351   unformat_input_t *input = vam->input;
19352   vl_api_classify_table_info_t *mp;
19353
19354   u32 table_id = ~0;
19355   int ret;
19356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (input, "table_id %d", &table_id))
19359         ;
19360       else
19361         break;
19362     }
19363   if (table_id == ~0)
19364     {
19365       errmsg ("missing table id");
19366       return -99;
19367     }
19368
19369   /* Construct the API message */
19370   M (CLASSIFY_TABLE_INFO, mp);
19371   mp->context = 0;
19372   mp->table_id = ntohl (table_id);
19373
19374   S (mp);
19375   W (ret);
19376   return ret;
19377 }
19378
19379 int
19380 api_classify_session_dump (vat_main_t * vam)
19381 {
19382   unformat_input_t *input = vam->input;
19383   vl_api_classify_session_dump_t *mp;
19384   vl_api_control_ping_t *mp_ping;
19385
19386   u32 table_id = ~0;
19387   int ret;
19388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (input, "table_id %d", &table_id))
19391         ;
19392       else
19393         break;
19394     }
19395   if (table_id == ~0)
19396     {
19397       errmsg ("missing table id");
19398       return -99;
19399     }
19400
19401   /* Construct the API message */
19402   M (CLASSIFY_SESSION_DUMP, mp);
19403   mp->context = 0;
19404   mp->table_id = ntohl (table_id);
19405   S (mp);
19406
19407   /* Use a control ping for synchronization */
19408   MPING (CONTROL_PING, mp_ping);
19409   S (mp_ping);
19410
19411   W (ret);
19412   return ret;
19413 }
19414
19415 static void
19416 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19417 {
19418   vat_main_t *vam = &vat_main;
19419
19420   print (vam->ofp, "collector_address %U, collector_port %d, "
19421          "src_address %U, vrf_id %d, path_mtu %u, "
19422          "template_interval %u, udp_checksum %d",
19423          format_ip4_address, mp->collector_address,
19424          ntohs (mp->collector_port),
19425          format_ip4_address, mp->src_address,
19426          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19427          ntohl (mp->template_interval), mp->udp_checksum);
19428
19429   vam->retval = 0;
19430   vam->result_ready = 1;
19431 }
19432
19433 static void
19434   vl_api_ipfix_exporter_details_t_handler_json
19435   (vl_api_ipfix_exporter_details_t * mp)
19436 {
19437   vat_main_t *vam = &vat_main;
19438   vat_json_node_t node;
19439   struct in_addr collector_address;
19440   struct in_addr src_address;
19441
19442   vat_json_init_object (&node);
19443   clib_memcpy (&collector_address, &mp->collector_address,
19444                sizeof (collector_address));
19445   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19446   vat_json_object_add_uint (&node, "collector_port",
19447                             ntohs (mp->collector_port));
19448   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19449   vat_json_object_add_ip4 (&node, "src_address", src_address);
19450   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19451   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19452   vat_json_object_add_uint (&node, "template_interval",
19453                             ntohl (mp->template_interval));
19454   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19455
19456   vat_json_print (vam->ofp, &node);
19457   vat_json_free (&node);
19458   vam->retval = 0;
19459   vam->result_ready = 1;
19460 }
19461
19462 int
19463 api_ipfix_exporter_dump (vat_main_t * vam)
19464 {
19465   vl_api_ipfix_exporter_dump_t *mp;
19466   int ret;
19467
19468   /* Construct the API message */
19469   M (IPFIX_EXPORTER_DUMP, mp);
19470   mp->context = 0;
19471
19472   S (mp);
19473   W (ret);
19474   return ret;
19475 }
19476
19477 static int
19478 api_ipfix_classify_stream_dump (vat_main_t * vam)
19479 {
19480   vl_api_ipfix_classify_stream_dump_t *mp;
19481   int ret;
19482
19483   /* Construct the API message */
19484   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19485   mp->context = 0;
19486
19487   S (mp);
19488   W (ret);
19489   return ret;
19490   /* NOTREACHED */
19491   return 0;
19492 }
19493
19494 static void
19495   vl_api_ipfix_classify_stream_details_t_handler
19496   (vl_api_ipfix_classify_stream_details_t * mp)
19497 {
19498   vat_main_t *vam = &vat_main;
19499   print (vam->ofp, "domain_id %d, src_port %d",
19500          ntohl (mp->domain_id), ntohs (mp->src_port));
19501   vam->retval = 0;
19502   vam->result_ready = 1;
19503 }
19504
19505 static void
19506   vl_api_ipfix_classify_stream_details_t_handler_json
19507   (vl_api_ipfix_classify_stream_details_t * mp)
19508 {
19509   vat_main_t *vam = &vat_main;
19510   vat_json_node_t node;
19511
19512   vat_json_init_object (&node);
19513   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19514   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19515
19516   vat_json_print (vam->ofp, &node);
19517   vat_json_free (&node);
19518   vam->retval = 0;
19519   vam->result_ready = 1;
19520 }
19521
19522 static int
19523 api_ipfix_classify_table_dump (vat_main_t * vam)
19524 {
19525   vl_api_ipfix_classify_table_dump_t *mp;
19526   vl_api_control_ping_t *mp_ping;
19527   int ret;
19528
19529   if (!vam->json_output)
19530     {
19531       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19532              "transport_protocol");
19533     }
19534
19535   /* Construct the API message */
19536   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19537
19538   /* send it... */
19539   S (mp);
19540
19541   /* Use a control ping for synchronization */
19542   MPING (CONTROL_PING, mp_ping);
19543   S (mp_ping);
19544
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static void
19550   vl_api_ipfix_classify_table_details_t_handler
19551   (vl_api_ipfix_classify_table_details_t * mp)
19552 {
19553   vat_main_t *vam = &vat_main;
19554   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19555          mp->transport_protocol);
19556 }
19557
19558 static void
19559   vl_api_ipfix_classify_table_details_t_handler_json
19560   (vl_api_ipfix_classify_table_details_t * mp)
19561 {
19562   vat_json_node_t *node = NULL;
19563   vat_main_t *vam = &vat_main;
19564
19565   if (VAT_JSON_ARRAY != vam->json_tree.type)
19566     {
19567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19568       vat_json_init_array (&vam->json_tree);
19569     }
19570
19571   node = vat_json_array_add (&vam->json_tree);
19572   vat_json_init_object (node);
19573
19574   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19575   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19576   vat_json_object_add_uint (node, "transport_protocol",
19577                             mp->transport_protocol);
19578 }
19579
19580 static int
19581 api_sw_interface_span_enable_disable (vat_main_t * vam)
19582 {
19583   unformat_input_t *i = vam->input;
19584   vl_api_sw_interface_span_enable_disable_t *mp;
19585   u32 src_sw_if_index = ~0;
19586   u32 dst_sw_if_index = ~0;
19587   u8 state = 3;
19588   int ret;
19589   u8 is_l2 = 0;
19590
19591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19592     {
19593       if (unformat
19594           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19595         ;
19596       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19597         ;
19598       else
19599         if (unformat
19600             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19601         ;
19602       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19603         ;
19604       else if (unformat (i, "disable"))
19605         state = 0;
19606       else if (unformat (i, "rx"))
19607         state = 1;
19608       else if (unformat (i, "tx"))
19609         state = 2;
19610       else if (unformat (i, "both"))
19611         state = 3;
19612       else if (unformat (i, "l2"))
19613         is_l2 = 1;
19614       else
19615         break;
19616     }
19617
19618   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19619
19620   mp->sw_if_index_from = htonl (src_sw_if_index);
19621   mp->sw_if_index_to = htonl (dst_sw_if_index);
19622   mp->state = state;
19623   mp->is_l2 = is_l2;
19624
19625   S (mp);
19626   W (ret);
19627   return ret;
19628 }
19629
19630 static void
19631 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19632                                             * mp)
19633 {
19634   vat_main_t *vam = &vat_main;
19635   u8 *sw_if_from_name = 0;
19636   u8 *sw_if_to_name = 0;
19637   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19638   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19639   char *states[] = { "none", "rx", "tx", "both" };
19640   hash_pair_t *p;
19641
19642   /* *INDENT-OFF* */
19643   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19644   ({
19645     if ((u32) p->value[0] == sw_if_index_from)
19646       {
19647         sw_if_from_name = (u8 *)(p->key);
19648         if (sw_if_to_name)
19649           break;
19650       }
19651     if ((u32) p->value[0] == sw_if_index_to)
19652       {
19653         sw_if_to_name = (u8 *)(p->key);
19654         if (sw_if_from_name)
19655           break;
19656       }
19657   }));
19658   /* *INDENT-ON* */
19659   print (vam->ofp, "%20s => %20s (%s) %s",
19660          sw_if_from_name, sw_if_to_name, states[mp->state],
19661          mp->is_l2 ? "l2" : "device");
19662 }
19663
19664 static void
19665   vl_api_sw_interface_span_details_t_handler_json
19666   (vl_api_sw_interface_span_details_t * mp)
19667 {
19668   vat_main_t *vam = &vat_main;
19669   vat_json_node_t *node = NULL;
19670   u8 *sw_if_from_name = 0;
19671   u8 *sw_if_to_name = 0;
19672   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19673   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
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
19694   if (VAT_JSON_ARRAY != vam->json_tree.type)
19695     {
19696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19697       vat_json_init_array (&vam->json_tree);
19698     }
19699   node = vat_json_array_add (&vam->json_tree);
19700
19701   vat_json_init_object (node);
19702   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19703   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19704   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19705   if (0 != sw_if_to_name)
19706     {
19707       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19708     }
19709   vat_json_object_add_uint (node, "state", mp->state);
19710   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19711 }
19712
19713 static int
19714 api_sw_interface_span_dump (vat_main_t * vam)
19715 {
19716   unformat_input_t *input = vam->input;
19717   vl_api_sw_interface_span_dump_t *mp;
19718   vl_api_control_ping_t *mp_ping;
19719   u8 is_l2 = 0;
19720   int ret;
19721
19722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat (input, "l2"))
19725         is_l2 = 1;
19726       else
19727         break;
19728     }
19729
19730   M (SW_INTERFACE_SPAN_DUMP, mp);
19731   mp->is_l2 = is_l2;
19732   S (mp);
19733
19734   /* Use a control ping for synchronization */
19735   MPING (CONTROL_PING, mp_ping);
19736   S (mp_ping);
19737
19738   W (ret);
19739   return ret;
19740 }
19741
19742 int
19743 api_pg_create_interface (vat_main_t * vam)
19744 {
19745   unformat_input_t *input = vam->input;
19746   vl_api_pg_create_interface_t *mp;
19747
19748   u32 if_id = ~0;
19749   int ret;
19750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19751     {
19752       if (unformat (input, "if_id %d", &if_id))
19753         ;
19754       else
19755         break;
19756     }
19757   if (if_id == ~0)
19758     {
19759       errmsg ("missing pg interface index");
19760       return -99;
19761     }
19762
19763   /* Construct the API message */
19764   M (PG_CREATE_INTERFACE, mp);
19765   mp->context = 0;
19766   mp->interface_id = ntohl (if_id);
19767
19768   S (mp);
19769   W (ret);
19770   return ret;
19771 }
19772
19773 int
19774 api_pg_capture (vat_main_t * vam)
19775 {
19776   unformat_input_t *input = vam->input;
19777   vl_api_pg_capture_t *mp;
19778
19779   u32 if_id = ~0;
19780   u8 enable = 1;
19781   u32 count = 1;
19782   u8 pcap_file_set = 0;
19783   u8 *pcap_file = 0;
19784   int ret;
19785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19786     {
19787       if (unformat (input, "if_id %d", &if_id))
19788         ;
19789       else if (unformat (input, "pcap %s", &pcap_file))
19790         pcap_file_set = 1;
19791       else if (unformat (input, "count %d", &count))
19792         ;
19793       else if (unformat (input, "disable"))
19794         enable = 0;
19795       else
19796         break;
19797     }
19798   if (if_id == ~0)
19799     {
19800       errmsg ("missing pg interface index");
19801       return -99;
19802     }
19803   if (pcap_file_set > 0)
19804     {
19805       if (vec_len (pcap_file) > 255)
19806         {
19807           errmsg ("pcap file name is too long");
19808           return -99;
19809         }
19810     }
19811
19812   u32 name_len = vec_len (pcap_file);
19813   /* Construct the API message */
19814   M (PG_CAPTURE, mp);
19815   mp->context = 0;
19816   mp->interface_id = ntohl (if_id);
19817   mp->is_enabled = enable;
19818   mp->count = ntohl (count);
19819   mp->pcap_name_length = ntohl (name_len);
19820   if (pcap_file_set != 0)
19821     {
19822       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19823     }
19824   vec_free (pcap_file);
19825
19826   S (mp);
19827   W (ret);
19828   return ret;
19829 }
19830
19831 int
19832 api_pg_enable_disable (vat_main_t * vam)
19833 {
19834   unformat_input_t *input = vam->input;
19835   vl_api_pg_enable_disable_t *mp;
19836
19837   u8 enable = 1;
19838   u8 stream_name_set = 0;
19839   u8 *stream_name = 0;
19840   int ret;
19841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19842     {
19843       if (unformat (input, "stream %s", &stream_name))
19844         stream_name_set = 1;
19845       else if (unformat (input, "disable"))
19846         enable = 0;
19847       else
19848         break;
19849     }
19850
19851   if (stream_name_set > 0)
19852     {
19853       if (vec_len (stream_name) > 255)
19854         {
19855           errmsg ("stream name too long");
19856           return -99;
19857         }
19858     }
19859
19860   u32 name_len = vec_len (stream_name);
19861   /* Construct the API message */
19862   M (PG_ENABLE_DISABLE, mp);
19863   mp->context = 0;
19864   mp->is_enabled = enable;
19865   if (stream_name_set != 0)
19866     {
19867       mp->stream_name_length = ntohl (name_len);
19868       clib_memcpy (mp->stream_name, stream_name, name_len);
19869     }
19870   vec_free (stream_name);
19871
19872   S (mp);
19873   W (ret);
19874   return ret;
19875 }
19876
19877 int
19878 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19879 {
19880   unformat_input_t *input = vam->input;
19881   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19882
19883   u16 *low_ports = 0;
19884   u16 *high_ports = 0;
19885   u16 this_low;
19886   u16 this_hi;
19887   vl_api_prefix_t prefix;
19888   u32 tmp, tmp2;
19889   u8 prefix_set = 0;
19890   u32 vrf_id = ~0;
19891   u8 is_add = 1;
19892   int ret;
19893
19894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19895     {
19896       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19897         prefix_set = 1;
19898       else if (unformat (input, "vrf %d", &vrf_id))
19899         ;
19900       else if (unformat (input, "del"))
19901         is_add = 0;
19902       else if (unformat (input, "port %d", &tmp))
19903         {
19904           if (tmp == 0 || tmp > 65535)
19905             {
19906               errmsg ("port %d out of range", tmp);
19907               return -99;
19908             }
19909           this_low = tmp;
19910           this_hi = this_low + 1;
19911           vec_add1 (low_ports, this_low);
19912           vec_add1 (high_ports, this_hi);
19913         }
19914       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19915         {
19916           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19917             {
19918               errmsg ("incorrect range parameters");
19919               return -99;
19920             }
19921           this_low = tmp;
19922           /* Note: in debug CLI +1 is added to high before
19923              passing to real fn that does "the work"
19924              (ip_source_and_port_range_check_add_del).
19925              This fn is a wrapper around the binary API fn a
19926              control plane will call, which expects this increment
19927              to have occurred. Hence letting the binary API control
19928              plane fn do the increment for consistency between VAT
19929              and other control planes.
19930            */
19931           this_hi = tmp2;
19932           vec_add1 (low_ports, this_low);
19933           vec_add1 (high_ports, this_hi);
19934         }
19935       else
19936         break;
19937     }
19938
19939   if (prefix_set == 0)
19940     {
19941       errmsg ("<address>/<mask> not specified");
19942       return -99;
19943     }
19944
19945   if (vrf_id == ~0)
19946     {
19947       errmsg ("VRF ID required, not specified");
19948       return -99;
19949     }
19950
19951   if (vrf_id == 0)
19952     {
19953       errmsg
19954         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19955       return -99;
19956     }
19957
19958   if (vec_len (low_ports) == 0)
19959     {
19960       errmsg ("At least one port or port range required");
19961       return -99;
19962     }
19963
19964   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19965
19966   mp->is_add = is_add;
19967
19968   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19969
19970   mp->number_of_ranges = vec_len (low_ports);
19971
19972   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19973   vec_free (low_ports);
19974
19975   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19976   vec_free (high_ports);
19977
19978   mp->vrf_id = ntohl (vrf_id);
19979
19980   S (mp);
19981   W (ret);
19982   return ret;
19983 }
19984
19985 int
19986 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19987 {
19988   unformat_input_t *input = vam->input;
19989   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19990   u32 sw_if_index = ~0;
19991   int vrf_set = 0;
19992   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19993   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19994   u8 is_add = 1;
19995   int ret;
19996
19997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19998     {
19999       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20000         ;
20001       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20002         ;
20003       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20004         vrf_set = 1;
20005       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20006         vrf_set = 1;
20007       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20008         vrf_set = 1;
20009       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20010         vrf_set = 1;
20011       else if (unformat (input, "del"))
20012         is_add = 0;
20013       else
20014         break;
20015     }
20016
20017   if (sw_if_index == ~0)
20018     {
20019       errmsg ("Interface required but not specified");
20020       return -99;
20021     }
20022
20023   if (vrf_set == 0)
20024     {
20025       errmsg ("VRF ID required but not specified");
20026       return -99;
20027     }
20028
20029   if (tcp_out_vrf_id == 0
20030       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20031     {
20032       errmsg
20033         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20034       return -99;
20035     }
20036
20037   /* Construct the API message */
20038   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20039
20040   mp->sw_if_index = ntohl (sw_if_index);
20041   mp->is_add = is_add;
20042   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20043   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20044   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20045   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20046
20047   /* send it... */
20048   S (mp);
20049
20050   /* Wait for a reply... */
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_set_punt (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_address_family_t af;
20060   vl_api_set_punt_t *mp;
20061   u32 protocol = ~0;
20062   u32 port = ~0;
20063   int is_add = 1;
20064   int ret;
20065
20066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20067     {
20068       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20069         ;
20070       else if (unformat (i, "protocol %d", &protocol))
20071         ;
20072       else if (unformat (i, "port %d", &port))
20073         ;
20074       else if (unformat (i, "del"))
20075         is_add = 0;
20076       else
20077         {
20078           clib_warning ("parse error '%U'", format_unformat_error, i);
20079           return -99;
20080         }
20081     }
20082
20083   M (SET_PUNT, mp);
20084
20085   mp->is_add = (u8) is_add;
20086   mp->punt.type = PUNT_API_TYPE_L4;
20087   mp->punt.punt.l4.af = af;
20088   mp->punt.punt.l4.protocol = (u8) protocol;
20089   mp->punt.punt.l4.port = htons ((u16) port);
20090
20091   S (mp);
20092   W (ret);
20093   return ret;
20094 }
20095
20096 static int
20097 api_delete_subif (vat_main_t * vam)
20098 {
20099   unformat_input_t *i = vam->input;
20100   vl_api_delete_subif_t *mp;
20101   u32 sw_if_index = ~0;
20102   int ret;
20103
20104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20105     {
20106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20107         ;
20108       if (unformat (i, "sw_if_index %d", &sw_if_index))
20109         ;
20110       else
20111         break;
20112     }
20113
20114   if (sw_if_index == ~0)
20115     {
20116       errmsg ("missing sw_if_index");
20117       return -99;
20118     }
20119
20120   /* Construct the API message */
20121   M (DELETE_SUBIF, mp);
20122   mp->sw_if_index = ntohl (sw_if_index);
20123
20124   S (mp);
20125   W (ret);
20126   return ret;
20127 }
20128
20129 #define foreach_pbb_vtr_op      \
20130 _("disable",  L2_VTR_DISABLED)  \
20131 _("pop",  L2_VTR_POP_2)         \
20132 _("push",  L2_VTR_PUSH_2)
20133
20134 static int
20135 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20136 {
20137   unformat_input_t *i = vam->input;
20138   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20139   u32 sw_if_index = ~0, vtr_op = ~0;
20140   u16 outer_tag = ~0;
20141   u8 dmac[6], smac[6];
20142   u8 dmac_set = 0, smac_set = 0;
20143   u16 vlanid = 0;
20144   u32 sid = ~0;
20145   u32 tmp;
20146   int ret;
20147
20148   /* Shut up coverity */
20149   clib_memset (dmac, 0, sizeof (dmac));
20150   clib_memset (smac, 0, sizeof (smac));
20151
20152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20153     {
20154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20155         ;
20156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20157         ;
20158       else if (unformat (i, "vtr_op %d", &vtr_op))
20159         ;
20160 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20161       foreach_pbb_vtr_op
20162 #undef _
20163         else if (unformat (i, "translate_pbb_stag"))
20164         {
20165           if (unformat (i, "%d", &tmp))
20166             {
20167               vtr_op = L2_VTR_TRANSLATE_2_1;
20168               outer_tag = tmp;
20169             }
20170           else
20171             {
20172               errmsg
20173                 ("translate_pbb_stag operation requires outer tag definition");
20174               return -99;
20175             }
20176         }
20177       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20178         dmac_set++;
20179       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20180         smac_set++;
20181       else if (unformat (i, "sid %d", &sid))
20182         ;
20183       else if (unformat (i, "vlanid %d", &tmp))
20184         vlanid = tmp;
20185       else
20186         {
20187           clib_warning ("parse error '%U'", format_unformat_error, i);
20188           return -99;
20189         }
20190     }
20191
20192   if ((sw_if_index == ~0) || (vtr_op == ~0))
20193     {
20194       errmsg ("missing sw_if_index or vtr operation");
20195       return -99;
20196     }
20197   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20198       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20199     {
20200       errmsg
20201         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20202       return -99;
20203     }
20204
20205   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20206   mp->sw_if_index = ntohl (sw_if_index);
20207   mp->vtr_op = ntohl (vtr_op);
20208   mp->outer_tag = ntohs (outer_tag);
20209   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20210   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20211   mp->b_vlanid = ntohs (vlanid);
20212   mp->i_sid = ntohl (sid);
20213
20214   S (mp);
20215   W (ret);
20216   return ret;
20217 }
20218
20219 static int
20220 api_flow_classify_set_interface (vat_main_t * vam)
20221 {
20222   unformat_input_t *i = vam->input;
20223   vl_api_flow_classify_set_interface_t *mp;
20224   u32 sw_if_index;
20225   int sw_if_index_set;
20226   u32 ip4_table_index = ~0;
20227   u32 ip6_table_index = ~0;
20228   u8 is_add = 1;
20229   int ret;
20230
20231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20232     {
20233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20234         sw_if_index_set = 1;
20235       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20236         sw_if_index_set = 1;
20237       else if (unformat (i, "del"))
20238         is_add = 0;
20239       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20240         ;
20241       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20242         ;
20243       else
20244         {
20245           clib_warning ("parse error '%U'", format_unformat_error, i);
20246           return -99;
20247         }
20248     }
20249
20250   if (sw_if_index_set == 0)
20251     {
20252       errmsg ("missing interface name or sw_if_index");
20253       return -99;
20254     }
20255
20256   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20257
20258   mp->sw_if_index = ntohl (sw_if_index);
20259   mp->ip4_table_index = ntohl (ip4_table_index);
20260   mp->ip6_table_index = ntohl (ip6_table_index);
20261   mp->is_add = is_add;
20262
20263   S (mp);
20264   W (ret);
20265   return ret;
20266 }
20267
20268 static int
20269 api_flow_classify_dump (vat_main_t * vam)
20270 {
20271   unformat_input_t *i = vam->input;
20272   vl_api_flow_classify_dump_t *mp;
20273   vl_api_control_ping_t *mp_ping;
20274   u8 type = FLOW_CLASSIFY_N_TABLES;
20275   int ret;
20276
20277   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20278     ;
20279   else
20280     {
20281       errmsg ("classify table type must be specified");
20282       return -99;
20283     }
20284
20285   if (!vam->json_output)
20286     {
20287       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20288     }
20289
20290   M (FLOW_CLASSIFY_DUMP, mp);
20291   mp->type = type;
20292   /* send it... */
20293   S (mp);
20294
20295   /* Use a control ping for synchronization */
20296   MPING (CONTROL_PING, mp_ping);
20297   S (mp_ping);
20298
20299   /* Wait for a reply... */
20300   W (ret);
20301   return ret;
20302 }
20303
20304 static int
20305 api_feature_enable_disable (vat_main_t * vam)
20306 {
20307   unformat_input_t *i = vam->input;
20308   vl_api_feature_enable_disable_t *mp;
20309   u8 *arc_name = 0;
20310   u8 *feature_name = 0;
20311   u32 sw_if_index = ~0;
20312   u8 enable = 1;
20313   int ret;
20314
20315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20316     {
20317       if (unformat (i, "arc_name %s", &arc_name))
20318         ;
20319       else if (unformat (i, "feature_name %s", &feature_name))
20320         ;
20321       else
20322         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20323         ;
20324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20325         ;
20326       else if (unformat (i, "disable"))
20327         enable = 0;
20328       else
20329         break;
20330     }
20331
20332   if (arc_name == 0)
20333     {
20334       errmsg ("missing arc name");
20335       return -99;
20336     }
20337   if (vec_len (arc_name) > 63)
20338     {
20339       errmsg ("arc name too long");
20340     }
20341
20342   if (feature_name == 0)
20343     {
20344       errmsg ("missing feature name");
20345       return -99;
20346     }
20347   if (vec_len (feature_name) > 63)
20348     {
20349       errmsg ("feature name too long");
20350     }
20351
20352   if (sw_if_index == ~0)
20353     {
20354       errmsg ("missing interface name or sw_if_index");
20355       return -99;
20356     }
20357
20358   /* Construct the API message */
20359   M (FEATURE_ENABLE_DISABLE, mp);
20360   mp->sw_if_index = ntohl (sw_if_index);
20361   mp->enable = enable;
20362   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20363   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20364   vec_free (arc_name);
20365   vec_free (feature_name);
20366
20367   S (mp);
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static int
20373 api_sw_interface_tag_add_del (vat_main_t * vam)
20374 {
20375   unformat_input_t *i = vam->input;
20376   vl_api_sw_interface_tag_add_del_t *mp;
20377   u32 sw_if_index = ~0;
20378   u8 *tag = 0;
20379   u8 enable = 1;
20380   int ret;
20381
20382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20383     {
20384       if (unformat (i, "tag %s", &tag))
20385         ;
20386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20387         ;
20388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20389         ;
20390       else if (unformat (i, "del"))
20391         enable = 0;
20392       else
20393         break;
20394     }
20395
20396   if (sw_if_index == ~0)
20397     {
20398       errmsg ("missing interface name or sw_if_index");
20399       return -99;
20400     }
20401
20402   if (enable && (tag == 0))
20403     {
20404       errmsg ("no tag specified");
20405       return -99;
20406     }
20407
20408   /* Construct the API message */
20409   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20410   mp->sw_if_index = ntohl (sw_if_index);
20411   mp->is_add = enable;
20412   if (enable)
20413     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20414   vec_free (tag);
20415
20416   S (mp);
20417   W (ret);
20418   return ret;
20419 }
20420
20421 static void vl_api_l2_xconnect_details_t_handler
20422   (vl_api_l2_xconnect_details_t * mp)
20423 {
20424   vat_main_t *vam = &vat_main;
20425
20426   print (vam->ofp, "%15d%15d",
20427          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20428 }
20429
20430 static void vl_api_l2_xconnect_details_t_handler_json
20431   (vl_api_l2_xconnect_details_t * mp)
20432 {
20433   vat_main_t *vam = &vat_main;
20434   vat_json_node_t *node = NULL;
20435
20436   if (VAT_JSON_ARRAY != vam->json_tree.type)
20437     {
20438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20439       vat_json_init_array (&vam->json_tree);
20440     }
20441   node = vat_json_array_add (&vam->json_tree);
20442
20443   vat_json_init_object (node);
20444   vat_json_object_add_uint (node, "rx_sw_if_index",
20445                             ntohl (mp->rx_sw_if_index));
20446   vat_json_object_add_uint (node, "tx_sw_if_index",
20447                             ntohl (mp->tx_sw_if_index));
20448 }
20449
20450 static int
20451 api_l2_xconnect_dump (vat_main_t * vam)
20452 {
20453   vl_api_l2_xconnect_dump_t *mp;
20454   vl_api_control_ping_t *mp_ping;
20455   int ret;
20456
20457   if (!vam->json_output)
20458     {
20459       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20460     }
20461
20462   M (L2_XCONNECT_DUMP, mp);
20463
20464   S (mp);
20465
20466   /* Use a control ping for synchronization */
20467   MPING (CONTROL_PING, mp_ping);
20468   S (mp_ping);
20469
20470   W (ret);
20471   return ret;
20472 }
20473
20474 static int
20475 api_hw_interface_set_mtu (vat_main_t * vam)
20476 {
20477   unformat_input_t *i = vam->input;
20478   vl_api_hw_interface_set_mtu_t *mp;
20479   u32 sw_if_index = ~0;
20480   u32 mtu = 0;
20481   int ret;
20482
20483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20484     {
20485       if (unformat (i, "mtu %d", &mtu))
20486         ;
20487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20488         ;
20489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20490         ;
20491       else
20492         break;
20493     }
20494
20495   if (sw_if_index == ~0)
20496     {
20497       errmsg ("missing interface name or sw_if_index");
20498       return -99;
20499     }
20500
20501   if (mtu == 0)
20502     {
20503       errmsg ("no mtu specified");
20504       return -99;
20505     }
20506
20507   /* Construct the API message */
20508   M (HW_INTERFACE_SET_MTU, mp);
20509   mp->sw_if_index = ntohl (sw_if_index);
20510   mp->mtu = ntohs ((u16) mtu);
20511
20512   S (mp);
20513   W (ret);
20514   return ret;
20515 }
20516
20517 static int
20518 api_p2p_ethernet_add (vat_main_t * vam)
20519 {
20520   unformat_input_t *i = vam->input;
20521   vl_api_p2p_ethernet_add_t *mp;
20522   u32 parent_if_index = ~0;
20523   u32 sub_id = ~0;
20524   u8 remote_mac[6];
20525   u8 mac_set = 0;
20526   int ret;
20527
20528   clib_memset (remote_mac, 0, sizeof (remote_mac));
20529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20530     {
20531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20532         ;
20533       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20534         ;
20535       else
20536         if (unformat
20537             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20538         mac_set++;
20539       else if (unformat (i, "sub_id %d", &sub_id))
20540         ;
20541       else
20542         {
20543           clib_warning ("parse error '%U'", format_unformat_error, i);
20544           return -99;
20545         }
20546     }
20547
20548   if (parent_if_index == ~0)
20549     {
20550       errmsg ("missing interface name or sw_if_index");
20551       return -99;
20552     }
20553   if (mac_set == 0)
20554     {
20555       errmsg ("missing remote mac address");
20556       return -99;
20557     }
20558   if (sub_id == ~0)
20559     {
20560       errmsg ("missing sub-interface id");
20561       return -99;
20562     }
20563
20564   M (P2P_ETHERNET_ADD, mp);
20565   mp->parent_if_index = ntohl (parent_if_index);
20566   mp->subif_id = ntohl (sub_id);
20567   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20568
20569   S (mp);
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static int
20575 api_p2p_ethernet_del (vat_main_t * vam)
20576 {
20577   unformat_input_t *i = vam->input;
20578   vl_api_p2p_ethernet_del_t *mp;
20579   u32 parent_if_index = ~0;
20580   u8 remote_mac[6];
20581   u8 mac_set = 0;
20582   int ret;
20583
20584   clib_memset (remote_mac, 0, sizeof (remote_mac));
20585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20586     {
20587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20588         ;
20589       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20590         ;
20591       else
20592         if (unformat
20593             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20594         mac_set++;
20595       else
20596         {
20597           clib_warning ("parse error '%U'", format_unformat_error, i);
20598           return -99;
20599         }
20600     }
20601
20602   if (parent_if_index == ~0)
20603     {
20604       errmsg ("missing interface name or sw_if_index");
20605       return -99;
20606     }
20607   if (mac_set == 0)
20608     {
20609       errmsg ("missing remote mac address");
20610       return -99;
20611     }
20612
20613   M (P2P_ETHERNET_DEL, mp);
20614   mp->parent_if_index = ntohl (parent_if_index);
20615   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20616
20617   S (mp);
20618   W (ret);
20619   return ret;
20620 }
20621
20622 static int
20623 api_lldp_config (vat_main_t * vam)
20624 {
20625   unformat_input_t *i = vam->input;
20626   vl_api_lldp_config_t *mp;
20627   int tx_hold = 0;
20628   int tx_interval = 0;
20629   u8 *sys_name = NULL;
20630   int ret;
20631
20632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20633     {
20634       if (unformat (i, "system-name %s", &sys_name))
20635         ;
20636       else if (unformat (i, "tx-hold %d", &tx_hold))
20637         ;
20638       else if (unformat (i, "tx-interval %d", &tx_interval))
20639         ;
20640       else
20641         {
20642           clib_warning ("parse error '%U'", format_unformat_error, i);
20643           return -99;
20644         }
20645     }
20646
20647   vec_add1 (sys_name, 0);
20648
20649   M (LLDP_CONFIG, mp);
20650   mp->tx_hold = htonl (tx_hold);
20651   mp->tx_interval = htonl (tx_interval);
20652   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20653   vec_free (sys_name);
20654
20655   S (mp);
20656   W (ret);
20657   return ret;
20658 }
20659
20660 static int
20661 api_sw_interface_set_lldp (vat_main_t * vam)
20662 {
20663   unformat_input_t *i = vam->input;
20664   vl_api_sw_interface_set_lldp_t *mp;
20665   u32 sw_if_index = ~0;
20666   u32 enable = 1;
20667   u8 *port_desc = NULL, *mgmt_oid = NULL;
20668   ip4_address_t ip4_addr;
20669   ip6_address_t ip6_addr;
20670   int ret;
20671
20672   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20673   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20674
20675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20676     {
20677       if (unformat (i, "disable"))
20678         enable = 0;
20679       else
20680         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20681         ;
20682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20683         ;
20684       else if (unformat (i, "port-desc %s", &port_desc))
20685         ;
20686       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20687         ;
20688       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20689         ;
20690       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20691         ;
20692       else
20693         break;
20694     }
20695
20696   if (sw_if_index == ~0)
20697     {
20698       errmsg ("missing interface name or sw_if_index");
20699       return -99;
20700     }
20701
20702   /* Construct the API message */
20703   vec_add1 (port_desc, 0);
20704   vec_add1 (mgmt_oid, 0);
20705   M (SW_INTERFACE_SET_LLDP, mp);
20706   mp->sw_if_index = ntohl (sw_if_index);
20707   mp->enable = enable;
20708   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20709   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20710   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20711   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20712   vec_free (port_desc);
20713   vec_free (mgmt_oid);
20714
20715   S (mp);
20716   W (ret);
20717   return ret;
20718 }
20719
20720 static int
20721 api_tcp_configure_src_addresses (vat_main_t * vam)
20722 {
20723   vl_api_tcp_configure_src_addresses_t *mp;
20724   unformat_input_t *i = vam->input;
20725   ip4_address_t v4first, v4last;
20726   ip6_address_t v6first, v6last;
20727   u8 range_set = 0;
20728   u32 vrf_id = 0;
20729   int ret;
20730
20731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20732     {
20733       if (unformat (i, "%U - %U",
20734                     unformat_ip4_address, &v4first,
20735                     unformat_ip4_address, &v4last))
20736         {
20737           if (range_set)
20738             {
20739               errmsg ("one range per message (range already set)");
20740               return -99;
20741             }
20742           range_set = 1;
20743         }
20744       else if (unformat (i, "%U - %U",
20745                          unformat_ip6_address, &v6first,
20746                          unformat_ip6_address, &v6last))
20747         {
20748           if (range_set)
20749             {
20750               errmsg ("one range per message (range already set)");
20751               return -99;
20752             }
20753           range_set = 2;
20754         }
20755       else if (unformat (i, "vrf %d", &vrf_id))
20756         ;
20757       else
20758         break;
20759     }
20760
20761   if (range_set == 0)
20762     {
20763       errmsg ("address range not set");
20764       return -99;
20765     }
20766
20767   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20768   mp->vrf_id = ntohl (vrf_id);
20769   /* ipv6? */
20770   if (range_set == 2)
20771     {
20772       mp->is_ipv6 = 1;
20773       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20774       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20775     }
20776   else
20777     {
20778       mp->is_ipv6 = 0;
20779       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20780       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20781     }
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static void vl_api_app_namespace_add_del_reply_t_handler
20788   (vl_api_app_namespace_add_del_reply_t * mp)
20789 {
20790   vat_main_t *vam = &vat_main;
20791   i32 retval = ntohl (mp->retval);
20792   if (vam->async_mode)
20793     {
20794       vam->async_errors += (retval < 0);
20795     }
20796   else
20797     {
20798       vam->retval = retval;
20799       if (retval == 0)
20800         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20801       vam->result_ready = 1;
20802     }
20803 }
20804
20805 static void vl_api_app_namespace_add_del_reply_t_handler_json
20806   (vl_api_app_namespace_add_del_reply_t * mp)
20807 {
20808   vat_main_t *vam = &vat_main;
20809   vat_json_node_t node;
20810
20811   vat_json_init_object (&node);
20812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20813   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20814
20815   vat_json_print (vam->ofp, &node);
20816   vat_json_free (&node);
20817
20818   vam->retval = ntohl (mp->retval);
20819   vam->result_ready = 1;
20820 }
20821
20822 static int
20823 api_app_namespace_add_del (vat_main_t * vam)
20824 {
20825   vl_api_app_namespace_add_del_t *mp;
20826   unformat_input_t *i = vam->input;
20827   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20828   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20829   u64 secret;
20830   int ret;
20831
20832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20833     {
20834       if (unformat (i, "id %_%v%_", &ns_id))
20835         ;
20836       else if (unformat (i, "secret %lu", &secret))
20837         secret_set = 1;
20838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20839         sw_if_index_set = 1;
20840       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20841         ;
20842       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20843         ;
20844       else
20845         break;
20846     }
20847   if (!ns_id || !secret_set || !sw_if_index_set)
20848     {
20849       errmsg ("namespace id, secret and sw_if_index must be set");
20850       return -99;
20851     }
20852   if (vec_len (ns_id) > 64)
20853     {
20854       errmsg ("namespace id too long");
20855       return -99;
20856     }
20857   M (APP_NAMESPACE_ADD_DEL, mp);
20858
20859   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20860   mp->namespace_id_len = vec_len (ns_id);
20861   mp->secret = clib_host_to_net_u64 (secret);
20862   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20863   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20864   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20865   vec_free (ns_id);
20866   S (mp);
20867   W (ret);
20868   return ret;
20869 }
20870
20871 static int
20872 api_sock_init_shm (vat_main_t * vam)
20873 {
20874 #if VPP_API_TEST_BUILTIN == 0
20875   unformat_input_t *i = vam->input;
20876   vl_api_shm_elem_config_t *config = 0;
20877   u64 size = 64 << 20;
20878   int rv;
20879
20880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20881     {
20882       if (unformat (i, "size %U", unformat_memory_size, &size))
20883         ;
20884       else
20885         break;
20886     }
20887
20888   /*
20889    * Canned custom ring allocator config.
20890    * Should probably parse all of this
20891    */
20892   vec_validate (config, 6);
20893   config[0].type = VL_API_VLIB_RING;
20894   config[0].size = 256;
20895   config[0].count = 32;
20896
20897   config[1].type = VL_API_VLIB_RING;
20898   config[1].size = 1024;
20899   config[1].count = 16;
20900
20901   config[2].type = VL_API_VLIB_RING;
20902   config[2].size = 4096;
20903   config[2].count = 2;
20904
20905   config[3].type = VL_API_CLIENT_RING;
20906   config[3].size = 256;
20907   config[3].count = 32;
20908
20909   config[4].type = VL_API_CLIENT_RING;
20910   config[4].size = 1024;
20911   config[4].count = 16;
20912
20913   config[5].type = VL_API_CLIENT_RING;
20914   config[5].size = 4096;
20915   config[5].count = 2;
20916
20917   config[6].type = VL_API_QUEUE;
20918   config[6].count = 128;
20919   config[6].size = sizeof (uword);
20920
20921   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20922   if (!rv)
20923     vam->client_index_invalid = 1;
20924   return rv;
20925 #else
20926   return -99;
20927 #endif
20928 }
20929
20930 static int
20931 api_dns_enable_disable (vat_main_t * vam)
20932 {
20933   unformat_input_t *line_input = vam->input;
20934   vl_api_dns_enable_disable_t *mp;
20935   u8 enable_disable = 1;
20936   int ret;
20937
20938   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20939     {
20940       if (unformat (line_input, "disable"))
20941         enable_disable = 0;
20942       if (unformat (line_input, "enable"))
20943         enable_disable = 1;
20944       else
20945         break;
20946     }
20947
20948   /* Construct the API message */
20949   M (DNS_ENABLE_DISABLE, mp);
20950   mp->enable = enable_disable;
20951
20952   /* send it... */
20953   S (mp);
20954   /* Wait for the reply */
20955   W (ret);
20956   return ret;
20957 }
20958
20959 static int
20960 api_dns_resolve_name (vat_main_t * vam)
20961 {
20962   unformat_input_t *line_input = vam->input;
20963   vl_api_dns_resolve_name_t *mp;
20964   u8 *name = 0;
20965   int ret;
20966
20967   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20968     {
20969       if (unformat (line_input, "%s", &name))
20970         ;
20971       else
20972         break;
20973     }
20974
20975   if (vec_len (name) > 127)
20976     {
20977       errmsg ("name too long");
20978       return -99;
20979     }
20980
20981   /* Construct the API message */
20982   M (DNS_RESOLVE_NAME, mp);
20983   memcpy (mp->name, name, vec_len (name));
20984   vec_free (name);
20985
20986   /* send it... */
20987   S (mp);
20988   /* Wait for the reply */
20989   W (ret);
20990   return ret;
20991 }
20992
20993 static int
20994 api_dns_resolve_ip (vat_main_t * vam)
20995 {
20996   unformat_input_t *line_input = vam->input;
20997   vl_api_dns_resolve_ip_t *mp;
20998   int is_ip6 = -1;
20999   ip4_address_t addr4;
21000   ip6_address_t addr6;
21001   int ret;
21002
21003   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21004     {
21005       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21006         is_ip6 = 1;
21007       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21008         is_ip6 = 0;
21009       else
21010         break;
21011     }
21012
21013   if (is_ip6 == -1)
21014     {
21015       errmsg ("missing address");
21016       return -99;
21017     }
21018
21019   /* Construct the API message */
21020   M (DNS_RESOLVE_IP, mp);
21021   mp->is_ip6 = is_ip6;
21022   if (is_ip6)
21023     memcpy (mp->address, &addr6, sizeof (addr6));
21024   else
21025     memcpy (mp->address, &addr4, sizeof (addr4));
21026
21027   /* send it... */
21028   S (mp);
21029   /* Wait for the reply */
21030   W (ret);
21031   return ret;
21032 }
21033
21034 static int
21035 api_dns_name_server_add_del (vat_main_t * vam)
21036 {
21037   unformat_input_t *i = vam->input;
21038   vl_api_dns_name_server_add_del_t *mp;
21039   u8 is_add = 1;
21040   ip6_address_t ip6_server;
21041   ip4_address_t ip4_server;
21042   int ip6_set = 0;
21043   int ip4_set = 0;
21044   int ret = 0;
21045
21046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21047     {
21048       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21049         ip6_set = 1;
21050       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21051         ip4_set = 1;
21052       else if (unformat (i, "del"))
21053         is_add = 0;
21054       else
21055         {
21056           clib_warning ("parse error '%U'", format_unformat_error, i);
21057           return -99;
21058         }
21059     }
21060
21061   if (ip4_set && ip6_set)
21062     {
21063       errmsg ("Only one server address allowed per message");
21064       return -99;
21065     }
21066   if ((ip4_set + ip6_set) == 0)
21067     {
21068       errmsg ("Server address required");
21069       return -99;
21070     }
21071
21072   /* Construct the API message */
21073   M (DNS_NAME_SERVER_ADD_DEL, mp);
21074
21075   if (ip6_set)
21076     {
21077       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21078       mp->is_ip6 = 1;
21079     }
21080   else
21081     {
21082       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21083       mp->is_ip6 = 0;
21084     }
21085
21086   mp->is_add = is_add;
21087
21088   /* send it... */
21089   S (mp);
21090
21091   /* Wait for a reply, return good/bad news  */
21092   W (ret);
21093   return ret;
21094 }
21095
21096 static void
21097 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21098 {
21099   vat_main_t *vam = &vat_main;
21100
21101   if (mp->is_ip4)
21102     {
21103       print (vam->ofp,
21104              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21105              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21106              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21107              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21108              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21109              clib_net_to_host_u32 (mp->action_index), mp->tag);
21110     }
21111   else
21112     {
21113       print (vam->ofp,
21114              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21115              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21116              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21117              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21118              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21119              clib_net_to_host_u32 (mp->action_index), mp->tag);
21120     }
21121 }
21122
21123 static void
21124 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21125                                              mp)
21126 {
21127   vat_main_t *vam = &vat_main;
21128   vat_json_node_t *node = NULL;
21129   struct in6_addr ip6;
21130   struct in_addr ip4;
21131
21132   if (VAT_JSON_ARRAY != vam->json_tree.type)
21133     {
21134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21135       vat_json_init_array (&vam->json_tree);
21136     }
21137   node = vat_json_array_add (&vam->json_tree);
21138   vat_json_init_object (node);
21139
21140   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21141   vat_json_object_add_uint (node, "appns_index",
21142                             clib_net_to_host_u32 (mp->appns_index));
21143   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21144   vat_json_object_add_uint (node, "scope", mp->scope);
21145   vat_json_object_add_uint (node, "action_index",
21146                             clib_net_to_host_u32 (mp->action_index));
21147   vat_json_object_add_uint (node, "lcl_port",
21148                             clib_net_to_host_u16 (mp->lcl_port));
21149   vat_json_object_add_uint (node, "rmt_port",
21150                             clib_net_to_host_u16 (mp->rmt_port));
21151   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21152   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21153   vat_json_object_add_string_copy (node, "tag", mp->tag);
21154   if (mp->is_ip4)
21155     {
21156       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21157       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21158       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21159       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21160     }
21161   else
21162     {
21163       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21164       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21165       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21166       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21167     }
21168 }
21169
21170 static int
21171 api_session_rule_add_del (vat_main_t * vam)
21172 {
21173   vl_api_session_rule_add_del_t *mp;
21174   unformat_input_t *i = vam->input;
21175   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21176   u32 appns_index = 0, scope = 0;
21177   ip4_address_t lcl_ip4, rmt_ip4;
21178   ip6_address_t lcl_ip6, rmt_ip6;
21179   u8 is_ip4 = 1, conn_set = 0;
21180   u8 is_add = 1, *tag = 0;
21181   int ret;
21182
21183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21184     {
21185       if (unformat (i, "del"))
21186         is_add = 0;
21187       else if (unformat (i, "add"))
21188         ;
21189       else if (unformat (i, "proto tcp"))
21190         proto = 0;
21191       else if (unformat (i, "proto udp"))
21192         proto = 1;
21193       else if (unformat (i, "appns %d", &appns_index))
21194         ;
21195       else if (unformat (i, "scope %d", &scope))
21196         ;
21197       else if (unformat (i, "tag %_%v%_", &tag))
21198         ;
21199       else
21200         if (unformat
21201             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21202              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21203              &rmt_port))
21204         {
21205           is_ip4 = 1;
21206           conn_set = 1;
21207         }
21208       else
21209         if (unformat
21210             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21211              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21212              &rmt_port))
21213         {
21214           is_ip4 = 0;
21215           conn_set = 1;
21216         }
21217       else if (unformat (i, "action %d", &action))
21218         ;
21219       else
21220         break;
21221     }
21222   if (proto == ~0 || !conn_set || action == ~0)
21223     {
21224       errmsg ("transport proto, connection and action must be set");
21225       return -99;
21226     }
21227
21228   if (scope > 3)
21229     {
21230       errmsg ("scope should be 0-3");
21231       return -99;
21232     }
21233
21234   M (SESSION_RULE_ADD_DEL, mp);
21235
21236   mp->is_ip4 = is_ip4;
21237   mp->transport_proto = proto;
21238   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21239   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21240   mp->lcl_plen = lcl_plen;
21241   mp->rmt_plen = rmt_plen;
21242   mp->action_index = clib_host_to_net_u32 (action);
21243   mp->appns_index = clib_host_to_net_u32 (appns_index);
21244   mp->scope = scope;
21245   mp->is_add = is_add;
21246   if (is_ip4)
21247     {
21248       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21249       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21250     }
21251   else
21252     {
21253       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21254       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21255     }
21256   if (tag)
21257     {
21258       clib_memcpy (mp->tag, tag, vec_len (tag));
21259       vec_free (tag);
21260     }
21261
21262   S (mp);
21263   W (ret);
21264   return ret;
21265 }
21266
21267 static int
21268 api_session_rules_dump (vat_main_t * vam)
21269 {
21270   vl_api_session_rules_dump_t *mp;
21271   vl_api_control_ping_t *mp_ping;
21272   int ret;
21273
21274   if (!vam->json_output)
21275     {
21276       print (vam->ofp, "%=20s", "Session Rules");
21277     }
21278
21279   M (SESSION_RULES_DUMP, mp);
21280   /* send it... */
21281   S (mp);
21282
21283   /* Use a control ping for synchronization */
21284   MPING (CONTROL_PING, mp_ping);
21285   S (mp_ping);
21286
21287   /* Wait for a reply... */
21288   W (ret);
21289   return ret;
21290 }
21291
21292 static int
21293 api_ip_container_proxy_add_del (vat_main_t * vam)
21294 {
21295   vl_api_ip_container_proxy_add_del_t *mp;
21296   unformat_input_t *i = vam->input;
21297   u32 sw_if_index = ~0;
21298   vl_api_prefix_t pfx = { };
21299   u8 is_add = 1;
21300   int ret;
21301
21302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21303     {
21304       if (unformat (i, "del"))
21305         is_add = 0;
21306       else if (unformat (i, "add"))
21307         ;
21308       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21309         ;
21310       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21311         ;
21312       else
21313         break;
21314     }
21315   if (sw_if_index == ~0 || pfx.address_length == 0)
21316     {
21317       errmsg ("address and sw_if_index must be set");
21318       return -99;
21319     }
21320
21321   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21322
21323   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21324   mp->is_add = is_add;
21325   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21326
21327   S (mp);
21328   W (ret);
21329   return ret;
21330 }
21331
21332 static int
21333 api_qos_record_enable_disable (vat_main_t * vam)
21334 {
21335   unformat_input_t *i = vam->input;
21336   vl_api_qos_record_enable_disable_t *mp;
21337   u32 sw_if_index, qs = 0xff;
21338   u8 sw_if_index_set = 0;
21339   u8 enable = 1;
21340   int ret;
21341
21342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21343     {
21344       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21345         sw_if_index_set = 1;
21346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21347         sw_if_index_set = 1;
21348       else if (unformat (i, "%U", unformat_qos_source, &qs))
21349         ;
21350       else if (unformat (i, "disable"))
21351         enable = 0;
21352       else
21353         {
21354           clib_warning ("parse error '%U'", format_unformat_error, i);
21355           return -99;
21356         }
21357     }
21358
21359   if (sw_if_index_set == 0)
21360     {
21361       errmsg ("missing interface name or sw_if_index");
21362       return -99;
21363     }
21364   if (qs == 0xff)
21365     {
21366       errmsg ("input location must be specified");
21367       return -99;
21368     }
21369
21370   M (QOS_RECORD_ENABLE_DISABLE, mp);
21371
21372   mp->sw_if_index = ntohl (sw_if_index);
21373   mp->input_source = qs;
21374   mp->enable = enable;
21375
21376   S (mp);
21377   W (ret);
21378   return ret;
21379 }
21380
21381
21382 static int
21383 q_or_quit (vat_main_t * vam)
21384 {
21385 #if VPP_API_TEST_BUILTIN == 0
21386   longjmp (vam->jump_buf, 1);
21387 #endif
21388   return 0;                     /* not so much */
21389 }
21390
21391 static int
21392 q (vat_main_t * vam)
21393 {
21394   return q_or_quit (vam);
21395 }
21396
21397 static int
21398 quit (vat_main_t * vam)
21399 {
21400   return q_or_quit (vam);
21401 }
21402
21403 static int
21404 comment (vat_main_t * vam)
21405 {
21406   return 0;
21407 }
21408
21409 static int
21410 statseg (vat_main_t * vam)
21411 {
21412   ssvm_private_t *ssvmp = &vam->stat_segment;
21413   ssvm_shared_header_t *shared_header = ssvmp->sh;
21414   vlib_counter_t **counters;
21415   u64 thread0_index1_packets;
21416   u64 thread0_index1_bytes;
21417   f64 vector_rate, input_rate;
21418   uword *p;
21419
21420   uword *counter_vector_by_name;
21421   if (vam->stat_segment_lockp == 0)
21422     {
21423       errmsg ("Stat segment not mapped...");
21424       return -99;
21425     }
21426
21427   /* look up "/if/rx for sw_if_index 1 as a test */
21428
21429   clib_spinlock_lock (vam->stat_segment_lockp);
21430
21431   counter_vector_by_name = (uword *) shared_header->opaque[1];
21432
21433   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21434   if (p == 0)
21435     {
21436       clib_spinlock_unlock (vam->stat_segment_lockp);
21437       errmsg ("/if/tx not found?");
21438       return -99;
21439     }
21440
21441   /* Fish per-thread vector of combined counters from shared memory */
21442   counters = (vlib_counter_t **) p[0];
21443
21444   if (vec_len (counters[0]) < 2)
21445     {
21446       clib_spinlock_unlock (vam->stat_segment_lockp);
21447       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21448       return -99;
21449     }
21450
21451   /* Read thread 0 sw_if_index 1 counter */
21452   thread0_index1_packets = counters[0][1].packets;
21453   thread0_index1_bytes = counters[0][1].bytes;
21454
21455   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21456   if (p == 0)
21457     {
21458       clib_spinlock_unlock (vam->stat_segment_lockp);
21459       errmsg ("vector_rate not found?");
21460       return -99;
21461     }
21462
21463   vector_rate = *(f64 *) (p[0]);
21464   p = hash_get_mem (counter_vector_by_name, "input_rate");
21465   if (p == 0)
21466     {
21467       clib_spinlock_unlock (vam->stat_segment_lockp);
21468       errmsg ("input_rate not found?");
21469       return -99;
21470     }
21471   input_rate = *(f64 *) (p[0]);
21472
21473   clib_spinlock_unlock (vam->stat_segment_lockp);
21474
21475   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21476          vector_rate, input_rate);
21477   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21478          thread0_index1_packets, thread0_index1_bytes);
21479
21480   return 0;
21481 }
21482
21483 static int
21484 cmd_cmp (void *a1, void *a2)
21485 {
21486   u8 **c1 = a1;
21487   u8 **c2 = a2;
21488
21489   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21490 }
21491
21492 static int
21493 help (vat_main_t * vam)
21494 {
21495   u8 **cmds = 0;
21496   u8 *name = 0;
21497   hash_pair_t *p;
21498   unformat_input_t *i = vam->input;
21499   int j;
21500
21501   if (unformat (i, "%s", &name))
21502     {
21503       uword *hs;
21504
21505       vec_add1 (name, 0);
21506
21507       hs = hash_get_mem (vam->help_by_name, name);
21508       if (hs)
21509         print (vam->ofp, "usage: %s %s", name, hs[0]);
21510       else
21511         print (vam->ofp, "No such msg / command '%s'", name);
21512       vec_free (name);
21513       return 0;
21514     }
21515
21516   print (vam->ofp, "Help is available for the following:");
21517
21518     /* *INDENT-OFF* */
21519     hash_foreach_pair (p, vam->function_by_name,
21520     ({
21521       vec_add1 (cmds, (u8 *)(p->key));
21522     }));
21523     /* *INDENT-ON* */
21524
21525   vec_sort_with_function (cmds, cmd_cmp);
21526
21527   for (j = 0; j < vec_len (cmds); j++)
21528     print (vam->ofp, "%s", cmds[j]);
21529
21530   vec_free (cmds);
21531   return 0;
21532 }
21533
21534 static int
21535 set (vat_main_t * vam)
21536 {
21537   u8 *name = 0, *value = 0;
21538   unformat_input_t *i = vam->input;
21539
21540   if (unformat (i, "%s", &name))
21541     {
21542       /* The input buffer is a vector, not a string. */
21543       value = vec_dup (i->buffer);
21544       vec_delete (value, i->index, 0);
21545       /* Almost certainly has a trailing newline */
21546       if (value[vec_len (value) - 1] == '\n')
21547         value[vec_len (value) - 1] = 0;
21548       /* Make sure it's a proper string, one way or the other */
21549       vec_add1 (value, 0);
21550       (void) clib_macro_set_value (&vam->macro_main,
21551                                    (char *) name, (char *) value);
21552     }
21553   else
21554     errmsg ("usage: set <name> <value>");
21555
21556   vec_free (name);
21557   vec_free (value);
21558   return 0;
21559 }
21560
21561 static int
21562 unset (vat_main_t * vam)
21563 {
21564   u8 *name = 0;
21565
21566   if (unformat (vam->input, "%s", &name))
21567     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21568       errmsg ("unset: %s wasn't set", name);
21569   vec_free (name);
21570   return 0;
21571 }
21572
21573 typedef struct
21574 {
21575   u8 *name;
21576   u8 *value;
21577 } macro_sort_t;
21578
21579
21580 static int
21581 macro_sort_cmp (void *a1, void *a2)
21582 {
21583   macro_sort_t *s1 = a1;
21584   macro_sort_t *s2 = a2;
21585
21586   return strcmp ((char *) (s1->name), (char *) (s2->name));
21587 }
21588
21589 static int
21590 dump_macro_table (vat_main_t * vam)
21591 {
21592   macro_sort_t *sort_me = 0, *sm;
21593   int i;
21594   hash_pair_t *p;
21595
21596     /* *INDENT-OFF* */
21597     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21598     ({
21599       vec_add2 (sort_me, sm, 1);
21600       sm->name = (u8 *)(p->key);
21601       sm->value = (u8 *) (p->value[0]);
21602     }));
21603     /* *INDENT-ON* */
21604
21605   vec_sort_with_function (sort_me, macro_sort_cmp);
21606
21607   if (vec_len (sort_me))
21608     print (vam->ofp, "%-15s%s", "Name", "Value");
21609   else
21610     print (vam->ofp, "The macro table is empty...");
21611
21612   for (i = 0; i < vec_len (sort_me); i++)
21613     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21614   return 0;
21615 }
21616
21617 static int
21618 dump_node_table (vat_main_t * vam)
21619 {
21620   int i, j;
21621   vlib_node_t *node, *next_node;
21622
21623   if (vec_len (vam->graph_nodes) == 0)
21624     {
21625       print (vam->ofp, "Node table empty, issue get_node_graph...");
21626       return 0;
21627     }
21628
21629   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21630     {
21631       node = vam->graph_nodes[0][i];
21632       print (vam->ofp, "[%d] %s", i, node->name);
21633       for (j = 0; j < vec_len (node->next_nodes); j++)
21634         {
21635           if (node->next_nodes[j] != ~0)
21636             {
21637               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21638               print (vam->ofp, "  [%d] %s", j, next_node->name);
21639             }
21640         }
21641     }
21642   return 0;
21643 }
21644
21645 static int
21646 value_sort_cmp (void *a1, void *a2)
21647 {
21648   name_sort_t *n1 = a1;
21649   name_sort_t *n2 = a2;
21650
21651   if (n1->value < n2->value)
21652     return -1;
21653   if (n1->value > n2->value)
21654     return 1;
21655   return 0;
21656 }
21657
21658
21659 static int
21660 dump_msg_api_table (vat_main_t * vam)
21661 {
21662   api_main_t *am = &api_main;
21663   name_sort_t *nses = 0, *ns;
21664   hash_pair_t *hp;
21665   int i;
21666
21667   /* *INDENT-OFF* */
21668   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21669   ({
21670     vec_add2 (nses, ns, 1);
21671     ns->name = (u8 *)(hp->key);
21672     ns->value = (u32) hp->value[0];
21673   }));
21674   /* *INDENT-ON* */
21675
21676   vec_sort_with_function (nses, value_sort_cmp);
21677
21678   for (i = 0; i < vec_len (nses); i++)
21679     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21680   vec_free (nses);
21681   return 0;
21682 }
21683
21684 static int
21685 get_msg_id (vat_main_t * vam)
21686 {
21687   u8 *name_and_crc;
21688   u32 message_index;
21689
21690   if (unformat (vam->input, "%s", &name_and_crc))
21691     {
21692       message_index = vl_msg_api_get_msg_index (name_and_crc);
21693       if (message_index == ~0)
21694         {
21695           print (vam->ofp, " '%s' not found", name_and_crc);
21696           return 0;
21697         }
21698       print (vam->ofp, " '%s' has message index %d",
21699              name_and_crc, message_index);
21700       return 0;
21701     }
21702   errmsg ("name_and_crc required...");
21703   return 0;
21704 }
21705
21706 static int
21707 search_node_table (vat_main_t * vam)
21708 {
21709   unformat_input_t *line_input = vam->input;
21710   u8 *node_to_find;
21711   int j;
21712   vlib_node_t *node, *next_node;
21713   uword *p;
21714
21715   if (vam->graph_node_index_by_name == 0)
21716     {
21717       print (vam->ofp, "Node table empty, issue get_node_graph...");
21718       return 0;
21719     }
21720
21721   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21722     {
21723       if (unformat (line_input, "%s", &node_to_find))
21724         {
21725           vec_add1 (node_to_find, 0);
21726           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21727           if (p == 0)
21728             {
21729               print (vam->ofp, "%s not found...", node_to_find);
21730               goto out;
21731             }
21732           node = vam->graph_nodes[0][p[0]];
21733           print (vam->ofp, "[%d] %s", p[0], node->name);
21734           for (j = 0; j < vec_len (node->next_nodes); j++)
21735             {
21736               if (node->next_nodes[j] != ~0)
21737                 {
21738                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21739                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21740                 }
21741             }
21742         }
21743
21744       else
21745         {
21746           clib_warning ("parse error '%U'", format_unformat_error,
21747                         line_input);
21748           return -99;
21749         }
21750
21751     out:
21752       vec_free (node_to_find);
21753
21754     }
21755
21756   return 0;
21757 }
21758
21759
21760 static int
21761 script (vat_main_t * vam)
21762 {
21763 #if (VPP_API_TEST_BUILTIN==0)
21764   u8 *s = 0;
21765   char *save_current_file;
21766   unformat_input_t save_input;
21767   jmp_buf save_jump_buf;
21768   u32 save_line_number;
21769
21770   FILE *new_fp, *save_ifp;
21771
21772   if (unformat (vam->input, "%s", &s))
21773     {
21774       new_fp = fopen ((char *) s, "r");
21775       if (new_fp == 0)
21776         {
21777           errmsg ("Couldn't open script file %s", s);
21778           vec_free (s);
21779           return -99;
21780         }
21781     }
21782   else
21783     {
21784       errmsg ("Missing script name");
21785       return -99;
21786     }
21787
21788   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21789   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21790   save_ifp = vam->ifp;
21791   save_line_number = vam->input_line_number;
21792   save_current_file = (char *) vam->current_file;
21793
21794   vam->input_line_number = 0;
21795   vam->ifp = new_fp;
21796   vam->current_file = s;
21797   do_one_file (vam);
21798
21799   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21800   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21801   vam->ifp = save_ifp;
21802   vam->input_line_number = save_line_number;
21803   vam->current_file = (u8 *) save_current_file;
21804   vec_free (s);
21805
21806   return 0;
21807 #else
21808   clib_warning ("use the exec command...");
21809   return -99;
21810 #endif
21811 }
21812
21813 static int
21814 echo (vat_main_t * vam)
21815 {
21816   print (vam->ofp, "%v", vam->input->buffer);
21817   return 0;
21818 }
21819
21820 /* List of API message constructors, CLI names map to api_xxx */
21821 #define foreach_vpe_api_msg                                             \
21822 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21823 _(sw_interface_dump,"")                                                 \
21824 _(sw_interface_set_flags,                                               \
21825   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21826 _(sw_interface_add_del_address,                                         \
21827   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21828 _(sw_interface_set_rx_mode,                                             \
21829   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21830 _(sw_interface_set_rx_placement,                                        \
21831   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21832 _(sw_interface_rx_placement_dump,                                       \
21833   "[<intfc> | sw_if_index <id>]")                                         \
21834 _(sw_interface_set_table,                                               \
21835   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21836 _(sw_interface_set_mpls_enable,                                         \
21837   "<intfc> | sw_if_index [disable | dis]")                              \
21838 _(sw_interface_set_vpath,                                               \
21839   "<intfc> | sw_if_index <id> enable | disable")                        \
21840 _(sw_interface_set_vxlan_bypass,                                        \
21841   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21842 _(sw_interface_set_geneve_bypass,                                       \
21843   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21844 _(sw_interface_set_l2_xconnect,                                         \
21845   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21846   "enable | disable")                                                   \
21847 _(sw_interface_set_l2_bridge,                                           \
21848   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21849   "[shg <split-horizon-group>] [bvi]\n"                                 \
21850   "enable | disable")                                                   \
21851 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21852 _(bridge_domain_add_del,                                                \
21853   "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") \
21854 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21855 _(l2fib_add_del,                                                        \
21856   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21857 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21858 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21859 _(l2_flags,                                                             \
21860   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21861 _(bridge_flags,                                                         \
21862   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21863 _(tap_create_v2,                                                        \
21864   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21865 _(tap_delete_v2,                                                        \
21866   "<vpp-if-name> | sw_if_index <id>")                                   \
21867 _(sw_interface_tap_v2_dump, "")                                         \
21868 _(virtio_pci_create,                                                    \
21869   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21870 _(virtio_pci_delete,                                                    \
21871   "<vpp-if-name> | sw_if_index <id>")                                   \
21872 _(sw_interface_virtio_pci_dump, "")                                     \
21873 _(bond_create,                                                          \
21874   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21875   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21876   "[id <if-id>]")                                                       \
21877 _(bond_delete,                                                          \
21878   "<vpp-if-name> | sw_if_index <id>")                                   \
21879 _(bond_enslave,                                                         \
21880   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21881 _(bond_detach_slave,                                                    \
21882   "sw_if_index <n>")                                                    \
21883 _(sw_interface_bond_dump, "")                                           \
21884 _(sw_interface_slave_dump,                                              \
21885   "<vpp-if-name> | sw_if_index <id>")                                   \
21886 _(ip_table_add_del,                                                     \
21887   "table <n> [ipv6] [add | del]\n")                                     \
21888 _(ip_route_add_del,                                                     \
21889   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21890   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21891   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21892   "[multipath] [count <n>] [del]")                                      \
21893 _(ip_mroute_add_del,                                                    \
21894   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21895   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21896 _(mpls_table_add_del,                                                   \
21897   "table <n> [add | del]\n")                                            \
21898 _(mpls_route_add_del,                                                   \
21899   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21900   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21901   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21902   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21903   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21904   "[count <n>] [del]")                                                  \
21905 _(mpls_ip_bind_unbind,                                                  \
21906   "<label> <addr/len>")                                                 \
21907 _(mpls_tunnel_add_del,                                                  \
21908   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21909   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21910   "[l2-only]  [out-label <n>]")                                         \
21911 _(sr_mpls_policy_add,                                                   \
21912   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21913 _(sr_mpls_policy_del,                                                   \
21914   "bsid <id>")                                                          \
21915 _(bier_table_add_del,                                                   \
21916   "<label> <sub-domain> <set> <bsl> [del]")                             \
21917 _(bier_route_add_del,                                                   \
21918   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21919   "[<intfc> | sw_if_index <id>]"                                        \
21920   "[weight <n>] [del] [multipath]")                                     \
21921 _(proxy_arp_add_del,                                                    \
21922   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21923 _(proxy_arp_intfc_enable_disable,                                       \
21924   "<intfc> | sw_if_index <id> enable | disable")                        \
21925 _(sw_interface_set_unnumbered,                                          \
21926   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21927 _(ip_neighbor_add_del,                                                  \
21928   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21929   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21930 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21931 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21932   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21933   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21934   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21935 _(reset_fib, "vrf <n> [ipv6]")                                          \
21936 _(dhcp_proxy_config,                                                    \
21937   "svr <v46-address> src <v46-address>\n"                               \
21938    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21939 _(dhcp_proxy_set_vss,                                                   \
21940   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21941 _(dhcp_proxy_dump, "ip6")                                               \
21942 _(dhcp_client_config,                                                   \
21943   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21944 _(set_ip_flow_hash,                                                     \
21945   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21946 _(sw_interface_ip6_enable_disable,                                      \
21947   "<intfc> | sw_if_index <id> enable | disable")                        \
21948 _(ip6nd_proxy_add_del,                                                  \
21949   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21950 _(ip6nd_proxy_dump, "")                                                 \
21951 _(sw_interface_ip6nd_ra_prefix,                                         \
21952   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21953   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21954   "[nolink] [isno]")                                                    \
21955 _(sw_interface_ip6nd_ra_config,                                         \
21956   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21957   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21958   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21959 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21960 _(l2_patch_add_del,                                                     \
21961   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21962   "enable | disable")                                                   \
21963 _(sr_localsid_add_del,                                                  \
21964   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21965   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21966 _(classify_add_del_table,                                               \
21967   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21968   " [del] [del-chain] mask <mask-value>\n"                              \
21969   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21970   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21971 _(classify_add_del_session,                                             \
21972   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21973   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21974   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21975   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21976 _(classify_set_interface_ip_table,                                      \
21977   "<intfc> | sw_if_index <nn> table <nn>")                              \
21978 _(classify_set_interface_l2_tables,                                     \
21979   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21980   "  [other-table <nn>]")                                               \
21981 _(get_node_index, "node <node-name")                                    \
21982 _(add_node_next, "node <node-name> next <next-node-name>")              \
21983 _(l2tpv3_create_tunnel,                                                 \
21984   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21985   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21986   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21987 _(l2tpv3_set_tunnel_cookies,                                            \
21988   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21989   "[new_remote_cookie <nn>]\n")                                         \
21990 _(l2tpv3_interface_enable_disable,                                      \
21991   "<intfc> | sw_if_index <nn> enable | disable")                        \
21992 _(l2tpv3_set_lookup_key,                                                \
21993   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21994 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21995 _(vxlan_offload_rx,                                                     \
21996   "hw { <interface name> | hw_if_index <nn>} "                          \
21997   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21998 _(vxlan_add_del_tunnel,                                                 \
21999   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22000   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22001   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22002 _(geneve_add_del_tunnel,                                                \
22003   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22004   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22005   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22006 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22007 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22008 _(gre_tunnel_add_del,                                                   \
22009   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22010   "[teb | erspan <session-id>] [del]")                                  \
22011 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22012 _(l2_fib_clear_table, "")                                               \
22013 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22014 _(l2_interface_vlan_tag_rewrite,                                        \
22015   "<intfc> | sw_if_index <nn> \n"                                       \
22016   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22017   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22018 _(create_vhost_user_if,                                                 \
22019         "socket <filename> [server] [renumber <dev_instance>] "         \
22020         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22021         "[mac <mac_address>]")                                          \
22022 _(modify_vhost_user_if,                                                 \
22023         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22024         "[server] [renumber <dev_instance>]")                           \
22025 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22026 _(sw_interface_vhost_user_dump, "")                                     \
22027 _(show_version, "")                                                     \
22028 _(show_threads, "")                                                     \
22029 _(vxlan_gpe_add_del_tunnel,                                             \
22030   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22031   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22032   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22033   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22034 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22035 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22036 _(interface_name_renumber,                                              \
22037   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22038 _(input_acl_set_interface,                                              \
22039   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22040   "  [l2-table <nn>] [del]")                                            \
22041 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22042 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22043   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22044 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22045 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22046 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22047 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22048 _(ip_dump, "ipv4 | ipv6")                                               \
22049 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22050 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22051   "  spid_id <n> ")                                                     \
22052 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22053   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22054   "  integ_alg <alg> integ_key <hex>")                                  \
22055 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22056   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22057   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22058   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22059 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22060   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22061   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22062   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22063   "  [instance <n>]")     \
22064 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22065 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22066 _(delete_loopback,"sw_if_index <nn>")                                   \
22067 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22068 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22069 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22070 _(want_interface_events,  "enable|disable")                             \
22071 _(get_first_msg_id, "client <name>")                                    \
22072 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22073 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22074   "fib-id <nn> [ip4][ip6][default]")                                    \
22075 _(get_node_graph, " ")                                                  \
22076 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22077 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22078 _(ioam_disable, "")                                                     \
22079 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22080                             " sw_if_index <sw_if_index> p <priority> "  \
22081                             "w <weight>] [del]")                        \
22082 _(one_add_del_locator, "locator-set <locator_name> "                    \
22083                         "iface <intf> | sw_if_index <sw_if_index> "     \
22084                         "p <priority> w <weight> [del]")                \
22085 _(one_add_del_local_eid,"vni <vni> eid "                                \
22086                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22087                          "locator-set <locator_name> [del]"             \
22088                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22089 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22090 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22091 _(one_enable_disable, "enable|disable")                                 \
22092 _(one_map_register_enable_disable, "enable|disable")                    \
22093 _(one_map_register_fallback_threshold, "<value>")                       \
22094 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22095 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22096                                "[seid <seid>] "                         \
22097                                "rloc <locator> p <prio> "               \
22098                                "w <weight> [rloc <loc> ... ] "          \
22099                                "action <action> [del-all]")             \
22100 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22101                           "<local-eid>")                                \
22102 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22103 _(one_use_petr, "ip-address> | disable")                                \
22104 _(one_map_request_mode, "src-dst|dst-only")                             \
22105 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22106 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22107 _(one_locator_set_dump, "[local | remote]")                             \
22108 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22109 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22110                        "[local] | [remote]")                            \
22111 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22112 _(one_ndp_bd_get, "")                                                   \
22113 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22114 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22115 _(one_l2_arp_bd_get, "")                                                \
22116 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22117 _(one_stats_enable_disable, "enable|disable")                           \
22118 _(show_one_stats_enable_disable, "")                                    \
22119 _(one_eid_table_vni_dump, "")                                           \
22120 _(one_eid_table_map_dump, "l2|l3")                                      \
22121 _(one_map_resolver_dump, "")                                            \
22122 _(one_map_server_dump, "")                                              \
22123 _(one_adjacencies_get, "vni <vni>")                                     \
22124 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22125 _(show_one_rloc_probe_state, "")                                        \
22126 _(show_one_map_register_state, "")                                      \
22127 _(show_one_status, "")                                                  \
22128 _(one_stats_dump, "")                                                   \
22129 _(one_stats_flush, "")                                                  \
22130 _(one_get_map_request_itr_rlocs, "")                                    \
22131 _(one_map_register_set_ttl, "<ttl>")                                    \
22132 _(one_set_transport_protocol, "udp|api")                                \
22133 _(one_get_transport_protocol, "")                                       \
22134 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22135 _(one_show_xtr_mode, "")                                                \
22136 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22137 _(one_show_pitr_mode, "")                                               \
22138 _(one_enable_disable_petr_mode, "enable|disable")                       \
22139 _(one_show_petr_mode, "")                                               \
22140 _(show_one_nsh_mapping, "")                                             \
22141 _(show_one_pitr, "")                                                    \
22142 _(show_one_use_petr, "")                                                \
22143 _(show_one_map_request_mode, "")                                        \
22144 _(show_one_map_register_ttl, "")                                        \
22145 _(show_one_map_register_fallback_threshold, "")                         \
22146 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22147                             " sw_if_index <sw_if_index> p <priority> "  \
22148                             "w <weight>] [del]")                        \
22149 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22150                         "iface <intf> | sw_if_index <sw_if_index> "     \
22151                         "p <priority> w <weight> [del]")                \
22152 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22153                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22154                          "locator-set <locator_name> [del]"             \
22155                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22156 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22157 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22158 _(lisp_enable_disable, "enable|disable")                                \
22159 _(lisp_map_register_enable_disable, "enable|disable")                   \
22160 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22161 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22162                                "[seid <seid>] "                         \
22163                                "rloc <locator> p <prio> "               \
22164                                "w <weight> [rloc <loc> ... ] "          \
22165                                "action <action> [del-all]")             \
22166 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22167                           "<local-eid>")                                \
22168 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22169 _(lisp_use_petr, "<ip-address> | disable")                              \
22170 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22171 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22172 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22173 _(lisp_locator_set_dump, "[local | remote]")                            \
22174 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22175 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22176                        "[local] | [remote]")                            \
22177 _(lisp_eid_table_vni_dump, "")                                          \
22178 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22179 _(lisp_map_resolver_dump, "")                                           \
22180 _(lisp_map_server_dump, "")                                             \
22181 _(lisp_adjacencies_get, "vni <vni>")                                    \
22182 _(gpe_fwd_entry_vnis_get, "")                                           \
22183 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22184 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22185                                 "[table <table-id>]")                   \
22186 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22187 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22188 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22189 _(gpe_get_encap_mode, "")                                               \
22190 _(lisp_gpe_add_del_iface, "up|down")                                    \
22191 _(lisp_gpe_enable_disable, "enable|disable")                            \
22192 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22193   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22194 _(show_lisp_rloc_probe_state, "")                                       \
22195 _(show_lisp_map_register_state, "")                                     \
22196 _(show_lisp_status, "")                                                 \
22197 _(lisp_get_map_request_itr_rlocs, "")                                   \
22198 _(show_lisp_pitr, "")                                                   \
22199 _(show_lisp_use_petr, "")                                               \
22200 _(show_lisp_map_request_mode, "")                                       \
22201 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22202 _(af_packet_delete, "name <host interface name>")                       \
22203 _(af_packet_dump, "")                                                   \
22204 _(policer_add_del, "name <policer name> <params> [del]")                \
22205 _(policer_dump, "[name <policer name>]")                                \
22206 _(policer_classify_set_interface,                                       \
22207   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22208   "  [l2-table <nn>] [del]")                                            \
22209 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22210 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22211     "[master|slave]")                                                   \
22212 _(netmap_delete, "name <interface name>")                               \
22213 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22214 _(mpls_table_dump, "")                                                  \
22215 _(mpls_route_dump, "table-id <ID>")                                     \
22216 _(classify_table_ids, "")                                               \
22217 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22218 _(classify_table_info, "table_id <nn>")                                 \
22219 _(classify_session_dump, "table_id <nn>")                               \
22220 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22221     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22222     "[template_interval <nn>] [udp_checksum]")                          \
22223 _(ipfix_exporter_dump, "")                                              \
22224 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22225 _(ipfix_classify_stream_dump, "")                                       \
22226 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22227 _(ipfix_classify_table_dump, "")                                        \
22228 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22229 _(sw_interface_span_dump, "[l2]")                                           \
22230 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22231 _(pg_create_interface, "if_id <nn>")                                    \
22232 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22233 _(pg_enable_disable, "[stream <id>] disable")                           \
22234 _(ip_source_and_port_range_check_add_del,                               \
22235   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22236 _(ip_source_and_port_range_check_interface_add_del,                     \
22237   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22238   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22239 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22240 _(l2_interface_pbb_tag_rewrite,                                         \
22241   "<intfc> | sw_if_index <nn> \n"                                       \
22242   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22243   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22244 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22245 _(flow_classify_set_interface,                                          \
22246   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22247 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22248 _(ip_table_dump, "")                                                    \
22249 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22250 _(ip_mtable_dump, "")                                                   \
22251 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22252 _(feature_enable_disable, "arc_name <arc_name> "                        \
22253   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22254 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22255 "[disable]")                                                            \
22256 _(l2_xconnect_dump, "")                                                 \
22257 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22258 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22259 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22260 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22261 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22262 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22263 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22264   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22265 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22266 _(sock_init_shm, "size <nnn>")                                          \
22267 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22268 _(dns_enable_disable, "[enable][disable]")                              \
22269 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22270 _(dns_resolve_name, "<hostname>")                                       \
22271 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22272 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22273 _(dns_resolve_name, "<hostname>")                                       \
22274 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22275   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22276 _(session_rules_dump, "")                                               \
22277 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22278 _(output_acl_set_interface,                                             \
22279   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22280   "  [l2-table <nn>] [del]")                                            \
22281 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22282
22283 /* List of command functions, CLI names map directly to functions */
22284 #define foreach_cli_function                                    \
22285 _(comment, "usage: comment <ignore-rest-of-line>")              \
22286 _(dump_interface_table, "usage: dump_interface_table")          \
22287 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22288 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22289 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22290 _(dump_macro_table, "usage: dump_macro_table ")                 \
22291 _(dump_node_table, "usage: dump_node_table")                    \
22292 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22293 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22294 _(echo, "usage: echo <message>")                                \
22295 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22296 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22297 _(help, "usage: help")                                          \
22298 _(q, "usage: quit")                                             \
22299 _(quit, "usage: quit")                                          \
22300 _(search_node_table, "usage: search_node_table <name>...")      \
22301 _(set, "usage: set <variable-name> <value>")                    \
22302 _(script, "usage: script <file-name>")                          \
22303 _(statseg, "usage: statseg")                                    \
22304 _(unset, "usage: unset <variable-name>")
22305
22306 #define _(N,n)                                  \
22307     static void vl_api_##n##_t_handler_uni      \
22308     (vl_api_##n##_t * mp)                       \
22309     {                                           \
22310         vat_main_t * vam = &vat_main;           \
22311         if (vam->json_output) {                 \
22312             vl_api_##n##_t_handler_json(mp);    \
22313         } else {                                \
22314             vl_api_##n##_t_handler(mp);         \
22315         }                                       \
22316     }
22317 foreach_vpe_api_reply_msg;
22318 #if VPP_API_TEST_BUILTIN == 0
22319 foreach_standalone_reply_msg;
22320 #endif
22321 #undef _
22322
22323 void
22324 vat_api_hookup (vat_main_t * vam)
22325 {
22326 #define _(N,n)                                                  \
22327     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22328                            vl_api_##n##_t_handler_uni,          \
22329                            vl_noop_handler,                     \
22330                            vl_api_##n##_t_endian,               \
22331                            vl_api_##n##_t_print,                \
22332                            sizeof(vl_api_##n##_t), 1);
22333   foreach_vpe_api_reply_msg;
22334 #if VPP_API_TEST_BUILTIN == 0
22335   foreach_standalone_reply_msg;
22336 #endif
22337 #undef _
22338
22339 #if (VPP_API_TEST_BUILTIN==0)
22340   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22341
22342   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22343
22344   vam->function_by_name = hash_create_string (0, sizeof (uword));
22345
22346   vam->help_by_name = hash_create_string (0, sizeof (uword));
22347 #endif
22348
22349   /* API messages we can send */
22350 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22351   foreach_vpe_api_msg;
22352 #undef _
22353
22354   /* Help strings */
22355 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22356   foreach_vpe_api_msg;
22357 #undef _
22358
22359   /* CLI functions */
22360 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22361   foreach_cli_function;
22362 #undef _
22363
22364   /* Help strings */
22365 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22366   foreach_cli_function;
22367 #undef _
22368 }
22369
22370 #if VPP_API_TEST_BUILTIN
22371 static clib_error_t *
22372 vat_api_hookup_shim (vlib_main_t * vm)
22373 {
22374   vat_api_hookup (&vat_main);
22375   return 0;
22376 }
22377
22378 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22379 #endif
22380
22381 /*
22382  * fd.io coding-style-patch-verification: ON
22383  *
22384  * Local Variables:
22385  * eval: (c-set-style "gnu")
22386  * End:
22387  */