l2: BD ARP termination entry API update
[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   u8 mac_address[6];
7433   u8 random_mac = 1;
7434   u32 id = ~0;
7435   u8 *host_if_name = 0;
7436   u8 *host_ns = 0;
7437   u8 host_mac_addr[6];
7438   u8 host_mac_addr_set = 0;
7439   u8 *host_bridge = 0;
7440   ip4_address_t host_ip4_addr;
7441   ip4_address_t host_ip4_gw;
7442   u8 host_ip4_gw_set = 0;
7443   u32 host_ip4_prefix_len = 0;
7444   ip6_address_t host_ip6_addr;
7445   ip6_address_t host_ip6_gw;
7446   u8 host_ip6_gw_set = 0;
7447   u32 host_ip6_prefix_len = 0;
7448   int ret;
7449   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7450
7451   clib_memset (mac_address, 0, sizeof (mac_address));
7452
7453   /* Parse args required to build the message */
7454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7455     {
7456       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7457         {
7458           random_mac = 0;
7459         }
7460       else if (unformat (i, "id %u", &id))
7461         ;
7462       else if (unformat (i, "host-if-name %s", &host_if_name))
7463         ;
7464       else if (unformat (i, "host-ns %s", &host_ns))
7465         ;
7466       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7467                          host_mac_addr))
7468         host_mac_addr_set = 1;
7469       else if (unformat (i, "host-bridge %s", &host_bridge))
7470         ;
7471       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7472                          &host_ip4_addr, &host_ip4_prefix_len))
7473         ;
7474       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7475                          &host_ip6_addr, &host_ip6_prefix_len))
7476         ;
7477       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7478                          &host_ip4_gw))
7479         host_ip4_gw_set = 1;
7480       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7481                          &host_ip6_gw))
7482         host_ip6_gw_set = 1;
7483       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7484         ;
7485       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7486         ;
7487       else
7488         break;
7489     }
7490
7491   if (vec_len (host_if_name) > 63)
7492     {
7493       errmsg ("tap name too long. ");
7494       return -99;
7495     }
7496   if (vec_len (host_ns) > 63)
7497     {
7498       errmsg ("host name space too long. ");
7499       return -99;
7500     }
7501   if (vec_len (host_bridge) > 63)
7502     {
7503       errmsg ("host bridge name too long. ");
7504       return -99;
7505     }
7506   if (host_ip4_prefix_len > 32)
7507     {
7508       errmsg ("host ip4 prefix length not valid. ");
7509       return -99;
7510     }
7511   if (host_ip6_prefix_len > 128)
7512     {
7513       errmsg ("host ip6 prefix length not valid. ");
7514       return -99;
7515     }
7516   if (!is_pow2 (rx_ring_sz))
7517     {
7518       errmsg ("rx ring size must be power of 2. ");
7519       return -99;
7520     }
7521   if (rx_ring_sz > 32768)
7522     {
7523       errmsg ("rx ring size must be 32768 or lower. ");
7524       return -99;
7525     }
7526   if (!is_pow2 (tx_ring_sz))
7527     {
7528       errmsg ("tx ring size must be power of 2. ");
7529       return -99;
7530     }
7531   if (tx_ring_sz > 32768)
7532     {
7533       errmsg ("tx ring size must be 32768 or lower. ");
7534       return -99;
7535     }
7536
7537   /* Construct the API message */
7538   M (TAP_CREATE_V2, mp);
7539
7540   mp->use_random_mac = random_mac;
7541
7542   mp->id = ntohl (id);
7543   mp->host_namespace_set = host_ns != 0;
7544   mp->host_bridge_set = host_bridge != 0;
7545   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7546   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7547   mp->rx_ring_sz = ntohs (rx_ring_sz);
7548   mp->tx_ring_sz = ntohs (tx_ring_sz);
7549
7550   if (random_mac == 0)
7551     clib_memcpy (mp->mac_address, mac_address, 6);
7552   if (host_mac_addr_set)
7553     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7554   if (host_if_name)
7555     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7556   if (host_ns)
7557     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7558   if (host_bridge)
7559     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7560   if (host_ip4_prefix_len)
7561     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7562   if (host_ip6_prefix_len)
7563     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7564   if (host_ip4_gw_set)
7565     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7566   if (host_ip6_gw_set)
7567     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7568
7569   vec_free (host_ns);
7570   vec_free (host_if_name);
7571   vec_free (host_bridge);
7572
7573   /* send it... */
7574   S (mp);
7575
7576   /* Wait for a reply... */
7577   W (ret);
7578   return ret;
7579 }
7580
7581 static int
7582 api_tap_delete_v2 (vat_main_t * vam)
7583 {
7584   unformat_input_t *i = vam->input;
7585   vl_api_tap_delete_v2_t *mp;
7586   u32 sw_if_index = ~0;
7587   u8 sw_if_index_set = 0;
7588   int ret;
7589
7590   /* Parse args required to build the message */
7591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7592     {
7593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7594         sw_if_index_set = 1;
7595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7596         sw_if_index_set = 1;
7597       else
7598         break;
7599     }
7600
7601   if (sw_if_index_set == 0)
7602     {
7603       errmsg ("missing vpp interface name. ");
7604       return -99;
7605     }
7606
7607   /* Construct the API message */
7608   M (TAP_DELETE_V2, mp);
7609
7610   mp->sw_if_index = ntohl (sw_if_index);
7611
7612   /* send it... */
7613   S (mp);
7614
7615   /* Wait for a reply... */
7616   W (ret);
7617   return ret;
7618 }
7619
7620 uword
7621 unformat_pci_addr (unformat_input_t * input, va_list * args)
7622 {
7623   struct pci_addr_t
7624   {
7625     u16 domain;
7626     u8 bus;
7627     u8 slot:5;
7628     u8 function:3;
7629   } *addr;
7630   addr = va_arg (*args, struct pci_addr_t *);
7631   u32 x[4];
7632
7633   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7634     return 0;
7635
7636   addr->domain = x[0];
7637   addr->bus = x[1];
7638   addr->slot = x[2];
7639   addr->function = x[3];
7640
7641   return 1;
7642 }
7643
7644 static int
7645 api_virtio_pci_create (vat_main_t * vam)
7646 {
7647   unformat_input_t *i = vam->input;
7648   vl_api_virtio_pci_create_t *mp;
7649   u8 mac_address[6];
7650   u8 random_mac = 1;
7651   u8 gso_enabled = 0;
7652   u32 pci_addr = 0;
7653   u64 features = (u64) ~ (0ULL);
7654   int ret;
7655
7656   clib_memset (mac_address, 0, sizeof (mac_address));
7657
7658   /* Parse args required to build the message */
7659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7660     {
7661       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7662         {
7663           random_mac = 0;
7664         }
7665       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7666         ;
7667       else if (unformat (i, "features 0x%llx", &features))
7668         ;
7669       else if (unformat (i, "gso-enabled"))
7670         gso_enabled = 1;
7671       else
7672         break;
7673     }
7674
7675   if (pci_addr == 0)
7676     {
7677       errmsg ("pci address must be non zero. ");
7678       return -99;
7679     }
7680
7681   /* Construct the API message */
7682   M (VIRTIO_PCI_CREATE, mp);
7683
7684   mp->use_random_mac = random_mac;
7685
7686   mp->pci_addr = htonl (pci_addr);
7687   mp->features = clib_host_to_net_u64 (features);
7688   mp->gso_enabled = gso_enabled;
7689
7690   if (random_mac == 0)
7691     clib_memcpy (mp->mac_address, mac_address, 6);
7692
7693   /* send it... */
7694   S (mp);
7695
7696   /* Wait for a reply... */
7697   W (ret);
7698   return ret;
7699 }
7700
7701 static int
7702 api_virtio_pci_delete (vat_main_t * vam)
7703 {
7704   unformat_input_t *i = vam->input;
7705   vl_api_virtio_pci_delete_t *mp;
7706   u32 sw_if_index = ~0;
7707   u8 sw_if_index_set = 0;
7708   int ret;
7709
7710   /* Parse args required to build the message */
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7714         sw_if_index_set = 1;
7715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7716         sw_if_index_set = 1;
7717       else
7718         break;
7719     }
7720
7721   if (sw_if_index_set == 0)
7722     {
7723       errmsg ("missing vpp interface name. ");
7724       return -99;
7725     }
7726
7727   /* Construct the API message */
7728   M (VIRTIO_PCI_DELETE, mp);
7729
7730   mp->sw_if_index = htonl (sw_if_index);
7731
7732   /* send it... */
7733   S (mp);
7734
7735   /* Wait for a reply... */
7736   W (ret);
7737   return ret;
7738 }
7739
7740 static int
7741 api_bond_create (vat_main_t * vam)
7742 {
7743   unformat_input_t *i = vam->input;
7744   vl_api_bond_create_t *mp;
7745   u8 mac_address[6];
7746   u8 custom_mac = 0;
7747   int ret;
7748   u8 mode;
7749   u8 lb;
7750   u8 mode_is_set = 0;
7751   u32 id = ~0;
7752
7753   clib_memset (mac_address, 0, sizeof (mac_address));
7754   lb = BOND_LB_L2;
7755
7756   /* Parse args required to build the message */
7757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758     {
7759       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7760         mode_is_set = 1;
7761       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7762                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7763         ;
7764       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7765                          mac_address))
7766         custom_mac = 1;
7767       else if (unformat (i, "id %u", &id))
7768         ;
7769       else
7770         break;
7771     }
7772
7773   if (mode_is_set == 0)
7774     {
7775       errmsg ("Missing bond mode. ");
7776       return -99;
7777     }
7778
7779   /* Construct the API message */
7780   M (BOND_CREATE, mp);
7781
7782   mp->use_custom_mac = custom_mac;
7783
7784   mp->mode = mode;
7785   mp->lb = lb;
7786   mp->id = htonl (id);
7787
7788   if (custom_mac)
7789     clib_memcpy (mp->mac_address, mac_address, 6);
7790
7791   /* send it... */
7792   S (mp);
7793
7794   /* Wait for a reply... */
7795   W (ret);
7796   return ret;
7797 }
7798
7799 static int
7800 api_bond_delete (vat_main_t * vam)
7801 {
7802   unformat_input_t *i = vam->input;
7803   vl_api_bond_delete_t *mp;
7804   u32 sw_if_index = ~0;
7805   u8 sw_if_index_set = 0;
7806   int ret;
7807
7808   /* Parse args required to build the message */
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7812         sw_if_index_set = 1;
7813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7814         sw_if_index_set = 1;
7815       else
7816         break;
7817     }
7818
7819   if (sw_if_index_set == 0)
7820     {
7821       errmsg ("missing vpp interface name. ");
7822       return -99;
7823     }
7824
7825   /* Construct the API message */
7826   M (BOND_DELETE, mp);
7827
7828   mp->sw_if_index = ntohl (sw_if_index);
7829
7830   /* send it... */
7831   S (mp);
7832
7833   /* Wait for a reply... */
7834   W (ret);
7835   return ret;
7836 }
7837
7838 static int
7839 api_bond_enslave (vat_main_t * vam)
7840 {
7841   unformat_input_t *i = vam->input;
7842   vl_api_bond_enslave_t *mp;
7843   u32 bond_sw_if_index;
7844   int ret;
7845   u8 is_passive;
7846   u8 is_long_timeout;
7847   u32 bond_sw_if_index_is_set = 0;
7848   u32 sw_if_index;
7849   u8 sw_if_index_is_set = 0;
7850
7851   /* Parse args required to build the message */
7852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7853     {
7854       if (unformat (i, "sw_if_index %d", &sw_if_index))
7855         sw_if_index_is_set = 1;
7856       else if (unformat (i, "bond %u", &bond_sw_if_index))
7857         bond_sw_if_index_is_set = 1;
7858       else if (unformat (i, "passive %d", &is_passive))
7859         ;
7860       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7861         ;
7862       else
7863         break;
7864     }
7865
7866   if (bond_sw_if_index_is_set == 0)
7867     {
7868       errmsg ("Missing bond sw_if_index. ");
7869       return -99;
7870     }
7871   if (sw_if_index_is_set == 0)
7872     {
7873       errmsg ("Missing slave sw_if_index. ");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (BOND_ENSLAVE, mp);
7879
7880   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7881   mp->sw_if_index = ntohl (sw_if_index);
7882   mp->is_long_timeout = is_long_timeout;
7883   mp->is_passive = is_passive;
7884
7885   /* send it... */
7886   S (mp);
7887
7888   /* Wait for a reply... */
7889   W (ret);
7890   return ret;
7891 }
7892
7893 static int
7894 api_bond_detach_slave (vat_main_t * vam)
7895 {
7896   unformat_input_t *i = vam->input;
7897   vl_api_bond_detach_slave_t *mp;
7898   u32 sw_if_index = ~0;
7899   u8 sw_if_index_set = 0;
7900   int ret;
7901
7902   /* Parse args required to build the message */
7903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7904     {
7905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7906         sw_if_index_set = 1;
7907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7908         sw_if_index_set = 1;
7909       else
7910         break;
7911     }
7912
7913   if (sw_if_index_set == 0)
7914     {
7915       errmsg ("missing vpp interface name. ");
7916       return -99;
7917     }
7918
7919   /* Construct the API message */
7920   M (BOND_DETACH_SLAVE, mp);
7921
7922   mp->sw_if_index = ntohl (sw_if_index);
7923
7924   /* send it... */
7925   S (mp);
7926
7927   /* Wait for a reply... */
7928   W (ret);
7929   return ret;
7930 }
7931
7932 static int
7933 api_ip_table_add_del (vat_main_t * vam)
7934 {
7935   unformat_input_t *i = vam->input;
7936   vl_api_ip_table_add_del_t *mp;
7937   u32 table_id = ~0;
7938   u8 is_ipv6 = 0;
7939   u8 is_add = 1;
7940   int ret = 0;
7941
7942   /* Parse args required to build the message */
7943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7944     {
7945       if (unformat (i, "ipv6"))
7946         is_ipv6 = 1;
7947       else if (unformat (i, "del"))
7948         is_add = 0;
7949       else if (unformat (i, "add"))
7950         is_add = 1;
7951       else if (unformat (i, "table %d", &table_id))
7952         ;
7953       else
7954         {
7955           clib_warning ("parse error '%U'", format_unformat_error, i);
7956           return -99;
7957         }
7958     }
7959
7960   if (~0 == table_id)
7961     {
7962       errmsg ("missing table-ID");
7963       return -99;
7964     }
7965
7966   /* Construct the API message */
7967   M (IP_TABLE_ADD_DEL, mp);
7968
7969   mp->table.table_id = ntohl (table_id);
7970   mp->table.is_ip6 = is_ipv6;
7971   mp->is_add = is_add;
7972
7973   /* send it... */
7974   S (mp);
7975
7976   /* Wait for a reply... */
7977   W (ret);
7978
7979   return ret;
7980 }
7981
7982 uword
7983 unformat_fib_path (unformat_input_t * input, va_list * args)
7984 {
7985   vat_main_t *vam = va_arg (*args, vat_main_t *);
7986   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7987   u32 weight, preference;
7988   mpls_label_t out_label;
7989
7990   clib_memset (path, 0, sizeof (*path));
7991   path->weight = 1;
7992   path->sw_if_index = ~0;
7993   path->rpf_id = ~0;
7994   path->n_labels = 0;
7995
7996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7997     {
7998       if (unformat (input, "%U %U",
7999                     unformat_vl_api_ip4_address,
8000                     &path->nh.address.ip4,
8001                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8002         {
8003           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8004         }
8005       else if (unformat (input, "%U %U",
8006                          unformat_vl_api_ip6_address,
8007                          &path->nh.address.ip6,
8008                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8009         {
8010           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8011         }
8012       else if (unformat (input, "weight %u", &weight))
8013         {
8014           path->weight = weight;
8015         }
8016       else if (unformat (input, "preference %u", &preference))
8017         {
8018           path->preference = preference;
8019         }
8020       else if (unformat (input, "%U next-hop-table %d",
8021                          unformat_vl_api_ip4_address,
8022                          &path->nh.address.ip4, &path->table_id))
8023         {
8024           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8025         }
8026       else if (unformat (input, "%U next-hop-table %d",
8027                          unformat_vl_api_ip6_address,
8028                          &path->nh.address.ip6, &path->table_id))
8029         {
8030           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8031         }
8032       else if (unformat (input, "%U",
8033                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8034         {
8035           /*
8036            * the recursive next-hops are by default in the default table
8037            */
8038           path->table_id = 0;
8039           path->sw_if_index = ~0;
8040           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8041         }
8042       else if (unformat (input, "%U",
8043                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8044         {
8045           /*
8046            * the recursive next-hops are by default in the default table
8047            */
8048           path->table_id = 0;
8049           path->sw_if_index = ~0;
8050           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8051         }
8052       else if (unformat (input, "resolve-via-host"))
8053         {
8054           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8055         }
8056       else if (unformat (input, "resolve-via-attached"))
8057         {
8058           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8059         }
8060       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8061         {
8062           path->type = FIB_API_PATH_TYPE_LOCAL;
8063           path->sw_if_index = ~0;
8064           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8065         }
8066       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8067         {
8068           path->type = FIB_API_PATH_TYPE_LOCAL;
8069           path->sw_if_index = ~0;
8070           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8071         }
8072       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8073         ;
8074       else if (unformat (input, "via-label %d", &path->nh.via_label))
8075         {
8076           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8077           path->sw_if_index = ~0;
8078         }
8079       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8080         {
8081           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8082           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8083         }
8084       else if (unformat (input, "local"))
8085         {
8086           path->type = FIB_API_PATH_TYPE_LOCAL;
8087         }
8088       else if (unformat (input, "out-labels"))
8089         {
8090           while (unformat (input, "%d", &out_label))
8091             {
8092               path->label_stack[path->n_labels].label = out_label;
8093               path->label_stack[path->n_labels].is_uniform = 0;
8094               path->label_stack[path->n_labels].ttl = 64;
8095               path->n_labels++;
8096             }
8097         }
8098       else if (unformat (input, "via"))
8099         {
8100           /* new path, back up and return */
8101           unformat_put_input (input);
8102           unformat_put_input (input);
8103           unformat_put_input (input);
8104           unformat_put_input (input);
8105           break;
8106         }
8107       else
8108         {
8109           return (0);
8110         }
8111     }
8112
8113   path->proto = ntohl (path->proto);
8114   path->type = ntohl (path->type);
8115   path->flags = ntohl (path->flags);
8116   path->table_id = ntohl (path->table_id);
8117   path->sw_if_index = ntohl (path->sw_if_index);
8118
8119   return (1);
8120 }
8121
8122 static int
8123 api_ip_route_add_del (vat_main_t * vam)
8124 {
8125   unformat_input_t *i = vam->input;
8126   vl_api_ip_route_add_del_t *mp;
8127   u32 vrf_id = 0;
8128   u8 is_add = 1;
8129   u8 is_multipath = 0;
8130   u8 prefix_set = 0;
8131   u8 path_count = 0;
8132   vl_api_prefix_t pfx = { };
8133   vl_api_fib_path_t paths[8];
8134   int count = 1;
8135   int j;
8136   f64 before = 0;
8137   u32 random_add_del = 0;
8138   u32 *random_vector = 0;
8139   u32 random_seed = 0xdeaddabe;
8140
8141   /* Parse args required to build the message */
8142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8143     {
8144       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8145         prefix_set = 1;
8146       else if (unformat (i, "del"))
8147         is_add = 0;
8148       else if (unformat (i, "add"))
8149         is_add = 1;
8150       else if (unformat (i, "vrf %d", &vrf_id))
8151         ;
8152       else if (unformat (i, "count %d", &count))
8153         ;
8154       else if (unformat (i, "random"))
8155         random_add_del = 1;
8156       else if (unformat (i, "multipath"))
8157         is_multipath = 1;
8158       else if (unformat (i, "seed %d", &random_seed))
8159         ;
8160       else
8161         if (unformat
8162             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8163         {
8164           path_count++;
8165           if (8 == path_count)
8166             {
8167               errmsg ("max 8 paths");
8168               return -99;
8169             }
8170         }
8171       else
8172         {
8173           clib_warning ("parse error '%U'", format_unformat_error, i);
8174           return -99;
8175         }
8176     }
8177
8178   if (!path_count)
8179     {
8180       errmsg ("specify a path; via ...");
8181       return -99;
8182     }
8183   if (prefix_set == 0)
8184     {
8185       errmsg ("missing prefix");
8186       return -99;
8187     }
8188
8189   /* Generate a pile of unique, random routes */
8190   if (random_add_del)
8191     {
8192       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8193       u32 this_random_address;
8194       uword *random_hash;
8195
8196       random_hash = hash_create (count, sizeof (uword));
8197
8198       hash_set (random_hash, i->as_u32, 1);
8199       for (j = 0; j <= count; j++)
8200         {
8201           do
8202             {
8203               this_random_address = random_u32 (&random_seed);
8204               this_random_address =
8205                 clib_host_to_net_u32 (this_random_address);
8206             }
8207           while (hash_get (random_hash, this_random_address));
8208           vec_add1 (random_vector, this_random_address);
8209           hash_set (random_hash, this_random_address, 1);
8210         }
8211       hash_free (random_hash);
8212       set_ip4_address (&pfx.address, random_vector[0]);
8213     }
8214
8215   if (count > 1)
8216     {
8217       /* Turn on async mode */
8218       vam->async_mode = 1;
8219       vam->async_errors = 0;
8220       before = vat_time_now (vam);
8221     }
8222
8223   for (j = 0; j < count; j++)
8224     {
8225       /* Construct the API message */
8226       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8227
8228       mp->is_add = is_add;
8229       mp->is_multipath = is_multipath;
8230
8231       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8232       mp->route.table_id = ntohl (vrf_id);
8233       mp->route.n_paths = path_count;
8234
8235       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8236
8237       if (random_add_del)
8238         set_ip4_address (&pfx.address, random_vector[j + 1]);
8239       else
8240         increment_address (&pfx.address);
8241       /* send it... */
8242       S (mp);
8243       /* If we receive SIGTERM, stop now... */
8244       if (vam->do_exit)
8245         break;
8246     }
8247
8248   /* When testing multiple add/del ops, use a control-ping to sync */
8249   if (count > 1)
8250     {
8251       vl_api_control_ping_t *mp_ping;
8252       f64 after;
8253       f64 timeout;
8254
8255       /* Shut off async mode */
8256       vam->async_mode = 0;
8257
8258       MPING (CONTROL_PING, mp_ping);
8259       S (mp_ping);
8260
8261       timeout = vat_time_now (vam) + 1.0;
8262       while (vat_time_now (vam) < timeout)
8263         if (vam->result_ready == 1)
8264           goto out;
8265       vam->retval = -99;
8266
8267     out:
8268       if (vam->retval == -99)
8269         errmsg ("timeout");
8270
8271       if (vam->async_errors > 0)
8272         {
8273           errmsg ("%d asynchronous errors", vam->async_errors);
8274           vam->retval = -98;
8275         }
8276       vam->async_errors = 0;
8277       after = vat_time_now (vam);
8278
8279       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8280       if (j > 0)
8281         count = j;
8282
8283       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8284              count, after - before, count / (after - before));
8285     }
8286   else
8287     {
8288       int ret;
8289
8290       /* Wait for a reply... */
8291       W (ret);
8292       return ret;
8293     }
8294
8295   /* Return the good/bad news */
8296   return (vam->retval);
8297 }
8298
8299 static int
8300 api_ip_mroute_add_del (vat_main_t * vam)
8301 {
8302   unformat_input_t *i = vam->input;
8303   u8 path_set = 0, prefix_set = 0, is_add = 1;
8304   vl_api_ip_mroute_add_del_t *mp;
8305   mfib_entry_flags_t eflags = 0;
8306   vl_api_mfib_path_t path;
8307   vl_api_mprefix_t pfx = { };
8308   u32 vrf_id = 0;
8309   int ret;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8315         {
8316           prefix_set = 1;
8317           pfx.grp_address_length = htons (pfx.grp_address_length);
8318         }
8319       else if (unformat (i, "del"))
8320         is_add = 0;
8321       else if (unformat (i, "add"))
8322         is_add = 1;
8323       else if (unformat (i, "vrf %d", &vrf_id))
8324         ;
8325       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8326         path.itf_flags = htonl (path.itf_flags);
8327       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8328         ;
8329       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8330         path_set = 1;
8331       else
8332         {
8333           clib_warning ("parse error '%U'", format_unformat_error, i);
8334           return -99;
8335         }
8336     }
8337
8338   if (prefix_set == 0)
8339     {
8340       errmsg ("missing addresses\n");
8341       return -99;
8342     }
8343   if (path_set == 0)
8344     {
8345       errmsg ("missing path\n");
8346       return -99;
8347     }
8348
8349   /* Construct the API message */
8350   M (IP_MROUTE_ADD_DEL, mp);
8351
8352   mp->is_add = is_add;
8353   mp->is_multipath = 1;
8354
8355   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8356   mp->route.table_id = htonl (vrf_id);
8357   mp->route.n_paths = 1;
8358   mp->route.entry_flags = htonl (eflags);
8359
8360   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8361
8362   /* send it... */
8363   S (mp);
8364   /* Wait for a reply... */
8365   W (ret);
8366   return ret;
8367 }
8368
8369 static int
8370 api_mpls_table_add_del (vat_main_t * vam)
8371 {
8372   unformat_input_t *i = vam->input;
8373   vl_api_mpls_table_add_del_t *mp;
8374   u32 table_id = ~0;
8375   u8 is_add = 1;
8376   int ret = 0;
8377
8378   /* Parse args required to build the message */
8379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (i, "table %d", &table_id))
8382         ;
8383       else if (unformat (i, "del"))
8384         is_add = 0;
8385       else if (unformat (i, "add"))
8386         is_add = 1;
8387       else
8388         {
8389           clib_warning ("parse error '%U'", format_unformat_error, i);
8390           return -99;
8391         }
8392     }
8393
8394   if (~0 == table_id)
8395     {
8396       errmsg ("missing table-ID");
8397       return -99;
8398     }
8399
8400   /* Construct the API message */
8401   M (MPLS_TABLE_ADD_DEL, mp);
8402
8403   mp->mt_table.mt_table_id = ntohl (table_id);
8404   mp->mt_is_add = is_add;
8405
8406   /* send it... */
8407   S (mp);
8408
8409   /* Wait for a reply... */
8410   W (ret);
8411
8412   return ret;
8413 }
8414
8415 static int
8416 api_mpls_route_add_del (vat_main_t * vam)
8417 {
8418   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8419   mpls_label_t local_label = MPLS_LABEL_INVALID;
8420   unformat_input_t *i = vam->input;
8421   vl_api_mpls_route_add_del_t *mp;
8422   vl_api_fib_path_t paths[8];
8423   int count = 1, j;
8424   f64 before = 0;
8425
8426   /* Parse args required to build the message */
8427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8428     {
8429       if (unformat (i, "%d", &local_label))
8430         ;
8431       else if (unformat (i, "eos"))
8432         is_eos = 1;
8433       else if (unformat (i, "non-eos"))
8434         is_eos = 0;
8435       else if (unformat (i, "del"))
8436         is_add = 0;
8437       else if (unformat (i, "add"))
8438         is_add = 1;
8439       else if (unformat (i, "multipath"))
8440         is_multipath = 1;
8441       else if (unformat (i, "count %d", &count))
8442         ;
8443       else
8444         if (unformat
8445             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8446         {
8447           path_count++;
8448           if (8 == path_count)
8449             {
8450               errmsg ("max 8 paths");
8451               return -99;
8452             }
8453         }
8454       else
8455         {
8456           clib_warning ("parse error '%U'", format_unformat_error, i);
8457           return -99;
8458         }
8459     }
8460
8461   if (!path_count)
8462     {
8463       errmsg ("specify a path; via ...");
8464       return -99;
8465     }
8466
8467   if (MPLS_LABEL_INVALID == local_label)
8468     {
8469       errmsg ("missing label");
8470       return -99;
8471     }
8472
8473   if (count > 1)
8474     {
8475       /* Turn on async mode */
8476       vam->async_mode = 1;
8477       vam->async_errors = 0;
8478       before = vat_time_now (vam);
8479     }
8480
8481   for (j = 0; j < count; j++)
8482     {
8483       /* Construct the API message */
8484       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8485
8486       mp->mr_is_add = is_add;
8487       mp->mr_is_multipath = is_multipath;
8488
8489       mp->mr_route.mr_label = local_label;
8490       mp->mr_route.mr_eos = is_eos;
8491       mp->mr_route.mr_table_id = 0;
8492       mp->mr_route.mr_n_paths = path_count;
8493
8494       clib_memcpy (&mp->mr_route.mr_paths, paths,
8495                    sizeof (paths[0]) * path_count);
8496
8497       local_label++;
8498
8499       /* send it... */
8500       S (mp);
8501       /* If we receive SIGTERM, stop now... */
8502       if (vam->do_exit)
8503         break;
8504     }
8505
8506   /* When testing multiple add/del ops, use a control-ping to sync */
8507   if (count > 1)
8508     {
8509       vl_api_control_ping_t *mp_ping;
8510       f64 after;
8511       f64 timeout;
8512
8513       /* Shut off async mode */
8514       vam->async_mode = 0;
8515
8516       MPING (CONTROL_PING, mp_ping);
8517       S (mp_ping);
8518
8519       timeout = vat_time_now (vam) + 1.0;
8520       while (vat_time_now (vam) < timeout)
8521         if (vam->result_ready == 1)
8522           goto out;
8523       vam->retval = -99;
8524
8525     out:
8526       if (vam->retval == -99)
8527         errmsg ("timeout");
8528
8529       if (vam->async_errors > 0)
8530         {
8531           errmsg ("%d asynchronous errors", vam->async_errors);
8532           vam->retval = -98;
8533         }
8534       vam->async_errors = 0;
8535       after = vat_time_now (vam);
8536
8537       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8538       if (j > 0)
8539         count = j;
8540
8541       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8542              count, after - before, count / (after - before));
8543     }
8544   else
8545     {
8546       int ret;
8547
8548       /* Wait for a reply... */
8549       W (ret);
8550       return ret;
8551     }
8552
8553   /* Return the good/bad news */
8554   return (vam->retval);
8555   return (0);
8556 }
8557
8558 static int
8559 api_mpls_ip_bind_unbind (vat_main_t * vam)
8560 {
8561   unformat_input_t *i = vam->input;
8562   vl_api_mpls_ip_bind_unbind_t *mp;
8563   u32 ip_table_id = 0;
8564   u8 is_bind = 1;
8565   vl_api_prefix_t pfx;
8566   u8 prefix_set = 0;
8567   mpls_label_t local_label = MPLS_LABEL_INVALID;
8568   int ret;
8569
8570   /* Parse args required to build the message */
8571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8572     {
8573       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8574         prefix_set = 1;
8575       else if (unformat (i, "%d", &local_label))
8576         ;
8577       else if (unformat (i, "table-id %d", &ip_table_id))
8578         ;
8579       else if (unformat (i, "unbind"))
8580         is_bind = 0;
8581       else if (unformat (i, "bind"))
8582         is_bind = 1;
8583       else
8584         {
8585           clib_warning ("parse error '%U'", format_unformat_error, i);
8586           return -99;
8587         }
8588     }
8589
8590   if (!prefix_set)
8591     {
8592       errmsg ("IP prefix not set");
8593       return -99;
8594     }
8595
8596   if (MPLS_LABEL_INVALID == local_label)
8597     {
8598       errmsg ("missing label");
8599       return -99;
8600     }
8601
8602   /* Construct the API message */
8603   M (MPLS_IP_BIND_UNBIND, mp);
8604
8605   mp->mb_is_bind = is_bind;
8606   mp->mb_ip_table_id = ntohl (ip_table_id);
8607   mp->mb_mpls_table_id = 0;
8608   mp->mb_label = ntohl (local_label);
8609   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8610
8611   /* send it... */
8612   S (mp);
8613
8614   /* Wait for a reply... */
8615   W (ret);
8616   return ret;
8617   return (0);
8618 }
8619
8620 static int
8621 api_sr_mpls_policy_add (vat_main_t * vam)
8622 {
8623   unformat_input_t *i = vam->input;
8624   vl_api_sr_mpls_policy_add_t *mp;
8625   u32 bsid = 0;
8626   u32 weight = 1;
8627   u8 type = 0;
8628   u8 n_segments = 0;
8629   u32 sid;
8630   u32 *segments = NULL;
8631   int ret;
8632
8633   /* Parse args required to build the message */
8634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8635     {
8636       if (unformat (i, "bsid %d", &bsid))
8637         ;
8638       else if (unformat (i, "weight %d", &weight))
8639         ;
8640       else if (unformat (i, "spray"))
8641         type = 1;
8642       else if (unformat (i, "next %d", &sid))
8643         {
8644           n_segments += 1;
8645           vec_add1 (segments, htonl (sid));
8646         }
8647       else
8648         {
8649           clib_warning ("parse error '%U'", format_unformat_error, i);
8650           return -99;
8651         }
8652     }
8653
8654   if (bsid == 0)
8655     {
8656       errmsg ("bsid not set");
8657       return -99;
8658     }
8659
8660   if (n_segments == 0)
8661     {
8662       errmsg ("no sid in segment stack");
8663       return -99;
8664     }
8665
8666   /* Construct the API message */
8667   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8668
8669   mp->bsid = htonl (bsid);
8670   mp->weight = htonl (weight);
8671   mp->type = type;
8672   mp->n_segments = n_segments;
8673   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8674   vec_free (segments);
8675
8676   /* send it... */
8677   S (mp);
8678
8679   /* Wait for a reply... */
8680   W (ret);
8681   return ret;
8682 }
8683
8684 static int
8685 api_sr_mpls_policy_del (vat_main_t * vam)
8686 {
8687   unformat_input_t *i = vam->input;
8688   vl_api_sr_mpls_policy_del_t *mp;
8689   u32 bsid = 0;
8690   int ret;
8691
8692   /* Parse args required to build the message */
8693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8694     {
8695       if (unformat (i, "bsid %d", &bsid))
8696         ;
8697       else
8698         {
8699           clib_warning ("parse error '%U'", format_unformat_error, i);
8700           return -99;
8701         }
8702     }
8703
8704   if (bsid == 0)
8705     {
8706       errmsg ("bsid not set");
8707       return -99;
8708     }
8709
8710   /* Construct the API message */
8711   M (SR_MPLS_POLICY_DEL, mp);
8712
8713   mp->bsid = htonl (bsid);
8714
8715   /* send it... */
8716   S (mp);
8717
8718   /* Wait for a reply... */
8719   W (ret);
8720   return ret;
8721 }
8722
8723 static int
8724 api_bier_table_add_del (vat_main_t * vam)
8725 {
8726   unformat_input_t *i = vam->input;
8727   vl_api_bier_table_add_del_t *mp;
8728   u8 is_add = 1;
8729   u32 set = 0, sub_domain = 0, hdr_len = 3;
8730   mpls_label_t local_label = MPLS_LABEL_INVALID;
8731   int ret;
8732
8733   /* Parse args required to build the message */
8734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8735     {
8736       if (unformat (i, "sub-domain %d", &sub_domain))
8737         ;
8738       else if (unformat (i, "set %d", &set))
8739         ;
8740       else if (unformat (i, "label %d", &local_label))
8741         ;
8742       else if (unformat (i, "hdr-len %d", &hdr_len))
8743         ;
8744       else if (unformat (i, "add"))
8745         is_add = 1;
8746       else if (unformat (i, "del"))
8747         is_add = 0;
8748       else
8749         {
8750           clib_warning ("parse error '%U'", format_unformat_error, i);
8751           return -99;
8752         }
8753     }
8754
8755   if (MPLS_LABEL_INVALID == local_label)
8756     {
8757       errmsg ("missing label\n");
8758       return -99;
8759     }
8760
8761   /* Construct the API message */
8762   M (BIER_TABLE_ADD_DEL, mp);
8763
8764   mp->bt_is_add = is_add;
8765   mp->bt_label = ntohl (local_label);
8766   mp->bt_tbl_id.bt_set = set;
8767   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8768   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8769
8770   /* send it... */
8771   S (mp);
8772
8773   /* Wait for a reply... */
8774   W (ret);
8775
8776   return (ret);
8777 }
8778
8779 static int
8780 api_bier_route_add_del (vat_main_t * vam)
8781 {
8782   unformat_input_t *i = vam->input;
8783   vl_api_bier_route_add_del_t *mp;
8784   u8 is_add = 1;
8785   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8786   ip4_address_t v4_next_hop_address;
8787   ip6_address_t v6_next_hop_address;
8788   u8 next_hop_set = 0;
8789   u8 next_hop_proto_is_ip4 = 1;
8790   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8791   int ret;
8792
8793   /* Parse args required to build the message */
8794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8797         {
8798           next_hop_proto_is_ip4 = 1;
8799           next_hop_set = 1;
8800         }
8801       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8802         {
8803           next_hop_proto_is_ip4 = 0;
8804           next_hop_set = 1;
8805         }
8806       if (unformat (i, "sub-domain %d", &sub_domain))
8807         ;
8808       else if (unformat (i, "set %d", &set))
8809         ;
8810       else if (unformat (i, "hdr-len %d", &hdr_len))
8811         ;
8812       else if (unformat (i, "bp %d", &bp))
8813         ;
8814       else if (unformat (i, "add"))
8815         is_add = 1;
8816       else if (unformat (i, "del"))
8817         is_add = 0;
8818       else if (unformat (i, "out-label %d", &next_hop_out_label))
8819         ;
8820       else
8821         {
8822           clib_warning ("parse error '%U'", format_unformat_error, i);
8823           return -99;
8824         }
8825     }
8826
8827   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8828     {
8829       errmsg ("next hop / label set\n");
8830       return -99;
8831     }
8832   if (0 == bp)
8833     {
8834       errmsg ("bit=position not set\n");
8835       return -99;
8836     }
8837
8838   /* Construct the API message */
8839   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8840
8841   mp->br_is_add = is_add;
8842   mp->br_route.br_tbl_id.bt_set = set;
8843   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8844   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8845   mp->br_route.br_bp = ntohs (bp);
8846   mp->br_route.br_n_paths = 1;
8847   mp->br_route.br_paths[0].n_labels = 1;
8848   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8849   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8850                                     FIB_API_PATH_NH_PROTO_IP4 :
8851                                     FIB_API_PATH_NH_PROTO_IP6);
8852
8853   if (next_hop_proto_is_ip4)
8854     {
8855       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8856                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8857     }
8858   else
8859     {
8860       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8861                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8862     }
8863
8864   /* send it... */
8865   S (mp);
8866
8867   /* Wait for a reply... */
8868   W (ret);
8869
8870   return (ret);
8871 }
8872
8873 static int
8874 api_proxy_arp_add_del (vat_main_t * vam)
8875 {
8876   unformat_input_t *i = vam->input;
8877   vl_api_proxy_arp_add_del_t *mp;
8878   u32 vrf_id = 0;
8879   u8 is_add = 1;
8880   vl_api_ip4_address_t lo, hi;
8881   u8 range_set = 0;
8882   int ret;
8883
8884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8885     {
8886       if (unformat (i, "vrf %d", &vrf_id))
8887         ;
8888       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8889                          unformat_vl_api_ip4_address, &hi))
8890         range_set = 1;
8891       else if (unformat (i, "del"))
8892         is_add = 0;
8893       else
8894         {
8895           clib_warning ("parse error '%U'", format_unformat_error, i);
8896           return -99;
8897         }
8898     }
8899
8900   if (range_set == 0)
8901     {
8902       errmsg ("address range not set");
8903       return -99;
8904     }
8905
8906   M (PROXY_ARP_ADD_DEL, mp);
8907
8908   mp->proxy.table_id = ntohl (vrf_id);
8909   mp->is_add = is_add;
8910   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8911   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8912
8913   S (mp);
8914   W (ret);
8915   return ret;
8916 }
8917
8918 static int
8919 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8923   u32 sw_if_index;
8924   u8 enable = 1;
8925   u8 sw_if_index_set = 0;
8926   int ret;
8927
8928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8929     {
8930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8931         sw_if_index_set = 1;
8932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8933         sw_if_index_set = 1;
8934       else if (unformat (i, "enable"))
8935         enable = 1;
8936       else if (unformat (i, "disable"))
8937         enable = 0;
8938       else
8939         {
8940           clib_warning ("parse error '%U'", format_unformat_error, i);
8941           return -99;
8942         }
8943     }
8944
8945   if (sw_if_index_set == 0)
8946     {
8947       errmsg ("missing interface name or sw_if_index");
8948       return -99;
8949     }
8950
8951   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8952
8953   mp->sw_if_index = ntohl (sw_if_index);
8954   mp->enable_disable = enable;
8955
8956   S (mp);
8957   W (ret);
8958   return ret;
8959 }
8960
8961 static int
8962 api_mpls_tunnel_add_del (vat_main_t * vam)
8963 {
8964   unformat_input_t *i = vam->input;
8965   vl_api_mpls_tunnel_add_del_t *mp;
8966
8967   vl_api_fib_path_t paths[8];
8968   u32 sw_if_index = ~0;
8969   u8 path_count = 0;
8970   u8 l2_only = 0;
8971   u8 is_add = 1;
8972   int ret;
8973
8974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8975     {
8976       if (unformat (i, "add"))
8977         is_add = 1;
8978       else
8979         if (unformat
8980             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8981         is_add = 0;
8982       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8983         is_add = 0;
8984       else if (unformat (i, "l2-only"))
8985         l2_only = 1;
8986       else
8987         if (unformat
8988             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8989         {
8990           path_count++;
8991           if (8 == path_count)
8992             {
8993               errmsg ("max 8 paths");
8994               return -99;
8995             }
8996         }
8997       else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9005
9006   mp->mt_is_add = is_add;
9007   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9008   mp->mt_tunnel.mt_l2_only = l2_only;
9009   mp->mt_tunnel.mt_is_multicast = 0;
9010   mp->mt_tunnel.mt_n_paths = path_count;
9011
9012   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9013                sizeof (paths[0]) * path_count);
9014
9015   S (mp);
9016   W (ret);
9017   return ret;
9018 }
9019
9020 static int
9021 api_sw_interface_set_unnumbered (vat_main_t * vam)
9022 {
9023   unformat_input_t *i = vam->input;
9024   vl_api_sw_interface_set_unnumbered_t *mp;
9025   u32 sw_if_index;
9026   u32 unnum_sw_index = ~0;
9027   u8 is_add = 1;
9028   u8 sw_if_index_set = 0;
9029   int ret;
9030
9031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9032     {
9033       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9034         sw_if_index_set = 1;
9035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9036         sw_if_index_set = 1;
9037       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9038         ;
9039       else if (unformat (i, "del"))
9040         is_add = 0;
9041       else
9042         {
9043           clib_warning ("parse error '%U'", format_unformat_error, i);
9044           return -99;
9045         }
9046     }
9047
9048   if (sw_if_index_set == 0)
9049     {
9050       errmsg ("missing interface name or sw_if_index");
9051       return -99;
9052     }
9053
9054   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9055
9056   mp->sw_if_index = ntohl (sw_if_index);
9057   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9058   mp->is_add = is_add;
9059
9060   S (mp);
9061   W (ret);
9062   return ret;
9063 }
9064
9065 static int
9066 api_ip_neighbor_add_del (vat_main_t * vam)
9067 {
9068   vl_api_mac_address_t mac_address;
9069   unformat_input_t *i = vam->input;
9070   vl_api_ip_neighbor_add_del_t *mp;
9071   vl_api_address_t ip_address;
9072   u32 sw_if_index;
9073   u8 sw_if_index_set = 0;
9074   u8 is_add = 1;
9075   u8 mac_set = 0;
9076   u8 address_set = 0;
9077   int ret;
9078   ip_neighbor_flags_t flags;
9079
9080   flags = IP_NEIGHBOR_FLAG_NONE;
9081   clib_memset (&ip_address, 0, sizeof (ip_address));
9082   clib_memset (&mac_address, 0, sizeof (mac_address));
9083
9084   /* Parse args required to build the message */
9085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9086     {
9087       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9088         {
9089           mac_set = 1;
9090         }
9091       else if (unformat (i, "del"))
9092         is_add = 0;
9093       else
9094         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9095         sw_if_index_set = 1;
9096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9097         sw_if_index_set = 1;
9098       else if (unformat (i, "static"))
9099         flags |= IP_NEIGHBOR_FLAG_STATIC;
9100       else if (unformat (i, "no-fib-entry"))
9101         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9102       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9103         address_set = 1;
9104       else
9105         {
9106           clib_warning ("parse error '%U'", format_unformat_error, i);
9107           return -99;
9108         }
9109     }
9110
9111   if (sw_if_index_set == 0)
9112     {
9113       errmsg ("missing interface name or sw_if_index");
9114       return -99;
9115     }
9116   if (!address_set)
9117     {
9118       errmsg ("no address set");
9119       return -99;
9120     }
9121
9122   /* Construct the API message */
9123   M (IP_NEIGHBOR_ADD_DEL, mp);
9124
9125   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9126   mp->is_add = is_add;
9127   mp->neighbor.flags = htonl (flags);
9128   if (mac_set)
9129     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9130                  sizeof (mac_address));
9131   if (address_set)
9132     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9133
9134   /* send it... */
9135   S (mp);
9136
9137   /* Wait for a reply, return good/bad news  */
9138   W (ret);
9139   return ret;
9140 }
9141
9142 static int
9143 api_create_vlan_subif (vat_main_t * vam)
9144 {
9145   unformat_input_t *i = vam->input;
9146   vl_api_create_vlan_subif_t *mp;
9147   u32 sw_if_index;
9148   u8 sw_if_index_set = 0;
9149   u32 vlan_id;
9150   u8 vlan_id_set = 0;
9151   int ret;
9152
9153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9154     {
9155       if (unformat (i, "sw_if_index %d", &sw_if_index))
9156         sw_if_index_set = 1;
9157       else
9158         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9159         sw_if_index_set = 1;
9160       else if (unformat (i, "vlan %d", &vlan_id))
9161         vlan_id_set = 1;
9162       else
9163         {
9164           clib_warning ("parse error '%U'", format_unformat_error, i);
9165           return -99;
9166         }
9167     }
9168
9169   if (sw_if_index_set == 0)
9170     {
9171       errmsg ("missing interface name or sw_if_index");
9172       return -99;
9173     }
9174
9175   if (vlan_id_set == 0)
9176     {
9177       errmsg ("missing vlan_id");
9178       return -99;
9179     }
9180   M (CREATE_VLAN_SUBIF, mp);
9181
9182   mp->sw_if_index = ntohl (sw_if_index);
9183   mp->vlan_id = ntohl (vlan_id);
9184
9185   S (mp);
9186   W (ret);
9187   return ret;
9188 }
9189
9190 #define foreach_create_subif_bit                \
9191 _(no_tags)                                      \
9192 _(one_tag)                                      \
9193 _(two_tags)                                     \
9194 _(dot1ad)                                       \
9195 _(exact_match)                                  \
9196 _(default_sub)                                  \
9197 _(outer_vlan_id_any)                            \
9198 _(inner_vlan_id_any)
9199
9200 static int
9201 api_create_subif (vat_main_t * vam)
9202 {
9203   unformat_input_t *i = vam->input;
9204   vl_api_create_subif_t *mp;
9205   u32 sw_if_index;
9206   u8 sw_if_index_set = 0;
9207   u32 sub_id;
9208   u8 sub_id_set = 0;
9209   u32 no_tags = 0;
9210   u32 one_tag = 0;
9211   u32 two_tags = 0;
9212   u32 dot1ad = 0;
9213   u32 exact_match = 0;
9214   u32 default_sub = 0;
9215   u32 outer_vlan_id_any = 0;
9216   u32 inner_vlan_id_any = 0;
9217   u32 tmp;
9218   u16 outer_vlan_id = 0;
9219   u16 inner_vlan_id = 0;
9220   int ret;
9221
9222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9223     {
9224       if (unformat (i, "sw_if_index %d", &sw_if_index))
9225         sw_if_index_set = 1;
9226       else
9227         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9228         sw_if_index_set = 1;
9229       else if (unformat (i, "sub_id %d", &sub_id))
9230         sub_id_set = 1;
9231       else if (unformat (i, "outer_vlan_id %d", &tmp))
9232         outer_vlan_id = tmp;
9233       else if (unformat (i, "inner_vlan_id %d", &tmp))
9234         inner_vlan_id = tmp;
9235
9236 #define _(a) else if (unformat (i, #a)) a = 1 ;
9237       foreach_create_subif_bit
9238 #undef _
9239         else
9240         {
9241           clib_warning ("parse error '%U'", format_unformat_error, i);
9242           return -99;
9243         }
9244     }
9245
9246   if (sw_if_index_set == 0)
9247     {
9248       errmsg ("missing interface name or sw_if_index");
9249       return -99;
9250     }
9251
9252   if (sub_id_set == 0)
9253     {
9254       errmsg ("missing sub_id");
9255       return -99;
9256     }
9257   M (CREATE_SUBIF, mp);
9258
9259   mp->sw_if_index = ntohl (sw_if_index);
9260   mp->sub_id = ntohl (sub_id);
9261
9262 #define _(a) mp->a = a;
9263   foreach_create_subif_bit;
9264 #undef _
9265
9266   mp->outer_vlan_id = ntohs (outer_vlan_id);
9267   mp->inner_vlan_id = ntohs (inner_vlan_id);
9268
9269   S (mp);
9270   W (ret);
9271   return ret;
9272 }
9273
9274 static int
9275 api_reset_fib (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_reset_fib_t *mp;
9279   u32 vrf_id = 0;
9280   u8 is_ipv6 = 0;
9281   u8 vrf_id_set = 0;
9282
9283   int ret;
9284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9285     {
9286       if (unformat (i, "vrf %d", &vrf_id))
9287         vrf_id_set = 1;
9288       else if (unformat (i, "ipv6"))
9289         is_ipv6 = 1;
9290       else
9291         {
9292           clib_warning ("parse error '%U'", format_unformat_error, i);
9293           return -99;
9294         }
9295     }
9296
9297   if (vrf_id_set == 0)
9298     {
9299       errmsg ("missing vrf id");
9300       return -99;
9301     }
9302
9303   M (RESET_FIB, mp);
9304
9305   mp->vrf_id = ntohl (vrf_id);
9306   mp->is_ipv6 = is_ipv6;
9307
9308   S (mp);
9309   W (ret);
9310   return ret;
9311 }
9312
9313 static int
9314 api_dhcp_proxy_config (vat_main_t * vam)
9315 {
9316   unformat_input_t *i = vam->input;
9317   vl_api_dhcp_proxy_config_t *mp;
9318   u32 rx_vrf_id = 0;
9319   u32 server_vrf_id = 0;
9320   u8 is_add = 1;
9321   u8 v4_address_set = 0;
9322   u8 v6_address_set = 0;
9323   ip4_address_t v4address;
9324   ip6_address_t v6address;
9325   u8 v4_src_address_set = 0;
9326   u8 v6_src_address_set = 0;
9327   ip4_address_t v4srcaddress;
9328   ip6_address_t v6srcaddress;
9329   int ret;
9330
9331   /* Parse args required to build the message */
9332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9333     {
9334       if (unformat (i, "del"))
9335         is_add = 0;
9336       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9337         ;
9338       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9339         ;
9340       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9341         v4_address_set = 1;
9342       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9343         v6_address_set = 1;
9344       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9345         v4_src_address_set = 1;
9346       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9347         v6_src_address_set = 1;
9348       else
9349         break;
9350     }
9351
9352   if (v4_address_set && v6_address_set)
9353     {
9354       errmsg ("both v4 and v6 server addresses set");
9355       return -99;
9356     }
9357   if (!v4_address_set && !v6_address_set)
9358     {
9359       errmsg ("no server addresses set");
9360       return -99;
9361     }
9362
9363   if (v4_src_address_set && v6_src_address_set)
9364     {
9365       errmsg ("both v4 and v6  src addresses set");
9366       return -99;
9367     }
9368   if (!v4_src_address_set && !v6_src_address_set)
9369     {
9370       errmsg ("no src addresses set");
9371       return -99;
9372     }
9373
9374   if (!(v4_src_address_set && v4_address_set) &&
9375       !(v6_src_address_set && v6_address_set))
9376     {
9377       errmsg ("no matching server and src addresses set");
9378       return -99;
9379     }
9380
9381   /* Construct the API message */
9382   M (DHCP_PROXY_CONFIG, mp);
9383
9384   mp->is_add = is_add;
9385   mp->rx_vrf_id = ntohl (rx_vrf_id);
9386   mp->server_vrf_id = ntohl (server_vrf_id);
9387   if (v6_address_set)
9388     {
9389       mp->is_ipv6 = 1;
9390       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9391       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9392     }
9393   else
9394     {
9395       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9396       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9397     }
9398
9399   /* send it... */
9400   S (mp);
9401
9402   /* Wait for a reply, return good/bad news  */
9403   W (ret);
9404   return ret;
9405 }
9406
9407 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9408 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9409
9410 static void
9411 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9412 {
9413   vat_main_t *vam = &vat_main;
9414   u32 i, count = mp->count;
9415   vl_api_dhcp_server_t *s;
9416
9417   if (mp->is_ipv6)
9418     print (vam->ofp,
9419            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9420            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9421            ntohl (mp->rx_vrf_id),
9422            format_ip6_address, mp->dhcp_src_address,
9423            mp->vss_type, mp->vss_vpn_ascii_id,
9424            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9425   else
9426     print (vam->ofp,
9427            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9428            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9429            ntohl (mp->rx_vrf_id),
9430            format_ip4_address, mp->dhcp_src_address,
9431            mp->vss_type, mp->vss_vpn_ascii_id,
9432            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9433
9434   for (i = 0; i < count; i++)
9435     {
9436       s = &mp->servers[i];
9437
9438       if (mp->is_ipv6)
9439         print (vam->ofp,
9440                " Server Table-ID %d, Server Address %U",
9441                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9442       else
9443         print (vam->ofp,
9444                " Server Table-ID %d, Server Address %U",
9445                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9446     }
9447 }
9448
9449 static void vl_api_dhcp_proxy_details_t_handler_json
9450   (vl_api_dhcp_proxy_details_t * mp)
9451 {
9452   vat_main_t *vam = &vat_main;
9453   vat_json_node_t *node = NULL;
9454   u32 i, count = mp->count;
9455   struct in_addr ip4;
9456   struct in6_addr ip6;
9457   vl_api_dhcp_server_t *s;
9458
9459   if (VAT_JSON_ARRAY != vam->json_tree.type)
9460     {
9461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9462       vat_json_init_array (&vam->json_tree);
9463     }
9464   node = vat_json_array_add (&vam->json_tree);
9465
9466   vat_json_init_object (node);
9467   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9468   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9469                              sizeof (mp->vss_type));
9470   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9471                                    mp->vss_vpn_ascii_id);
9472   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9473   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9474
9475   if (mp->is_ipv6)
9476     {
9477       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9478       vat_json_object_add_ip6 (node, "src_address", ip6);
9479     }
9480   else
9481     {
9482       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9483       vat_json_object_add_ip4 (node, "src_address", ip4);
9484     }
9485
9486   for (i = 0; i < count; i++)
9487     {
9488       s = &mp->servers[i];
9489
9490       vat_json_object_add_uint (node, "server-table-id",
9491                                 ntohl (s->server_vrf_id));
9492
9493       if (mp->is_ipv6)
9494         {
9495           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9496           vat_json_object_add_ip4 (node, "src_address", ip4);
9497         }
9498       else
9499         {
9500           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9501           vat_json_object_add_ip6 (node, "server_address", ip6);
9502         }
9503     }
9504 }
9505
9506 static int
9507 api_dhcp_proxy_dump (vat_main_t * vam)
9508 {
9509   unformat_input_t *i = vam->input;
9510   vl_api_control_ping_t *mp_ping;
9511   vl_api_dhcp_proxy_dump_t *mp;
9512   u8 is_ipv6 = 0;
9513   int ret;
9514
9515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9516     {
9517       if (unformat (i, "ipv6"))
9518         is_ipv6 = 1;
9519       else
9520         {
9521           clib_warning ("parse error '%U'", format_unformat_error, i);
9522           return -99;
9523         }
9524     }
9525
9526   M (DHCP_PROXY_DUMP, mp);
9527
9528   mp->is_ip6 = is_ipv6;
9529   S (mp);
9530
9531   /* Use a control ping for synchronization */
9532   MPING (CONTROL_PING, mp_ping);
9533   S (mp_ping);
9534
9535   W (ret);
9536   return ret;
9537 }
9538
9539 static int
9540 api_dhcp_proxy_set_vss (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_dhcp_proxy_set_vss_t *mp;
9544   u8 is_ipv6 = 0;
9545   u8 is_add = 1;
9546   u32 tbl_id = ~0;
9547   u8 vss_type = VSS_TYPE_DEFAULT;
9548   u8 *vpn_ascii_id = 0;
9549   u32 oui = 0;
9550   u32 fib_id = 0;
9551   int ret;
9552
9553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9554     {
9555       if (unformat (i, "tbl_id %d", &tbl_id))
9556         ;
9557       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9558         vss_type = VSS_TYPE_ASCII;
9559       else if (unformat (i, "fib_id %d", &fib_id))
9560         vss_type = VSS_TYPE_VPN_ID;
9561       else if (unformat (i, "oui %d", &oui))
9562         vss_type = VSS_TYPE_VPN_ID;
9563       else if (unformat (i, "ipv6"))
9564         is_ipv6 = 1;
9565       else if (unformat (i, "del"))
9566         is_add = 0;
9567       else
9568         break;
9569     }
9570
9571   if (tbl_id == ~0)
9572     {
9573       errmsg ("missing tbl_id ");
9574       vec_free (vpn_ascii_id);
9575       return -99;
9576     }
9577
9578   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9579     {
9580       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9581       vec_free (vpn_ascii_id);
9582       return -99;
9583     }
9584
9585   M (DHCP_PROXY_SET_VSS, mp);
9586   mp->tbl_id = ntohl (tbl_id);
9587   mp->vss_type = vss_type;
9588   if (vpn_ascii_id)
9589     {
9590       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9591       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9592     }
9593   mp->vpn_index = ntohl (fib_id);
9594   mp->oui = ntohl (oui);
9595   mp->is_ipv6 = is_ipv6;
9596   mp->is_add = is_add;
9597
9598   S (mp);
9599   W (ret);
9600
9601   vec_free (vpn_ascii_id);
9602   return ret;
9603 }
9604
9605 static int
9606 api_dhcp_client_config (vat_main_t * vam)
9607 {
9608   unformat_input_t *i = vam->input;
9609   vl_api_dhcp_client_config_t *mp;
9610   u32 sw_if_index;
9611   u8 sw_if_index_set = 0;
9612   u8 is_add = 1;
9613   u8 *hostname = 0;
9614   u8 disable_event = 0;
9615   int ret;
9616
9617   /* Parse args required to build the message */
9618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9619     {
9620       if (unformat (i, "del"))
9621         is_add = 0;
9622       else
9623         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9624         sw_if_index_set = 1;
9625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9626         sw_if_index_set = 1;
9627       else if (unformat (i, "hostname %s", &hostname))
9628         ;
9629       else if (unformat (i, "disable_event"))
9630         disable_event = 1;
9631       else
9632         break;
9633     }
9634
9635   if (sw_if_index_set == 0)
9636     {
9637       errmsg ("missing interface name or sw_if_index");
9638       return -99;
9639     }
9640
9641   if (vec_len (hostname) > 63)
9642     {
9643       errmsg ("hostname too long");
9644     }
9645   vec_add1 (hostname, 0);
9646
9647   /* Construct the API message */
9648   M (DHCP_CLIENT_CONFIG, mp);
9649
9650   mp->is_add = is_add;
9651   mp->client.sw_if_index = htonl (sw_if_index);
9652   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9653   vec_free (hostname);
9654   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9655   mp->client.pid = htonl (getpid ());
9656
9657   /* send it... */
9658   S (mp);
9659
9660   /* Wait for a reply, return good/bad news  */
9661   W (ret);
9662   return ret;
9663 }
9664
9665 static int
9666 api_set_ip_flow_hash (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_set_ip_flow_hash_t *mp;
9670   u32 vrf_id = 0;
9671   u8 is_ipv6 = 0;
9672   u8 vrf_id_set = 0;
9673   u8 src = 0;
9674   u8 dst = 0;
9675   u8 sport = 0;
9676   u8 dport = 0;
9677   u8 proto = 0;
9678   u8 reverse = 0;
9679   int ret;
9680
9681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9682     {
9683       if (unformat (i, "vrf %d", &vrf_id))
9684         vrf_id_set = 1;
9685       else if (unformat (i, "ipv6"))
9686         is_ipv6 = 1;
9687       else if (unformat (i, "src"))
9688         src = 1;
9689       else if (unformat (i, "dst"))
9690         dst = 1;
9691       else if (unformat (i, "sport"))
9692         sport = 1;
9693       else if (unformat (i, "dport"))
9694         dport = 1;
9695       else if (unformat (i, "proto"))
9696         proto = 1;
9697       else if (unformat (i, "reverse"))
9698         reverse = 1;
9699
9700       else
9701         {
9702           clib_warning ("parse error '%U'", format_unformat_error, i);
9703           return -99;
9704         }
9705     }
9706
9707   if (vrf_id_set == 0)
9708     {
9709       errmsg ("missing vrf id");
9710       return -99;
9711     }
9712
9713   M (SET_IP_FLOW_HASH, mp);
9714   mp->src = src;
9715   mp->dst = dst;
9716   mp->sport = sport;
9717   mp->dport = dport;
9718   mp->proto = proto;
9719   mp->reverse = reverse;
9720   mp->vrf_id = ntohl (vrf_id);
9721   mp->is_ipv6 = is_ipv6;
9722
9723   S (mp);
9724   W (ret);
9725   return ret;
9726 }
9727
9728 static int
9729 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9730 {
9731   unformat_input_t *i = vam->input;
9732   vl_api_sw_interface_ip6_enable_disable_t *mp;
9733   u32 sw_if_index;
9734   u8 sw_if_index_set = 0;
9735   u8 enable = 0;
9736   int ret;
9737
9738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9739     {
9740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9741         sw_if_index_set = 1;
9742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9743         sw_if_index_set = 1;
9744       else if (unformat (i, "enable"))
9745         enable = 1;
9746       else if (unformat (i, "disable"))
9747         enable = 0;
9748       else
9749         {
9750           clib_warning ("parse error '%U'", format_unformat_error, i);
9751           return -99;
9752         }
9753     }
9754
9755   if (sw_if_index_set == 0)
9756     {
9757       errmsg ("missing interface name or sw_if_index");
9758       return -99;
9759     }
9760
9761   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9762
9763   mp->sw_if_index = ntohl (sw_if_index);
9764   mp->enable = enable;
9765
9766   S (mp);
9767   W (ret);
9768   return ret;
9769 }
9770
9771 static int
9772 api_ip6nd_proxy_add_del (vat_main_t * vam)
9773 {
9774   unformat_input_t *i = vam->input;
9775   vl_api_ip6nd_proxy_add_del_t *mp;
9776   u32 sw_if_index = ~0;
9777   u8 v6_address_set = 0;
9778   vl_api_ip6_address_t v6address;
9779   u8 is_del = 0;
9780   int ret;
9781
9782   /* Parse args required to build the message */
9783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9784     {
9785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9786         ;
9787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9788         ;
9789       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9790         v6_address_set = 1;
9791       if (unformat (i, "del"))
9792         is_del = 1;
9793       else
9794         {
9795           clib_warning ("parse error '%U'", format_unformat_error, i);
9796           return -99;
9797         }
9798     }
9799
9800   if (sw_if_index == ~0)
9801     {
9802       errmsg ("missing interface name or sw_if_index");
9803       return -99;
9804     }
9805   if (!v6_address_set)
9806     {
9807       errmsg ("no address set");
9808       return -99;
9809     }
9810
9811   /* Construct the API message */
9812   M (IP6ND_PROXY_ADD_DEL, mp);
9813
9814   mp->is_del = is_del;
9815   mp->sw_if_index = ntohl (sw_if_index);
9816   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9817
9818   /* send it... */
9819   S (mp);
9820
9821   /* Wait for a reply, return good/bad news  */
9822   W (ret);
9823   return ret;
9824 }
9825
9826 static int
9827 api_ip6nd_proxy_dump (vat_main_t * vam)
9828 {
9829   vl_api_ip6nd_proxy_dump_t *mp;
9830   vl_api_control_ping_t *mp_ping;
9831   int ret;
9832
9833   M (IP6ND_PROXY_DUMP, mp);
9834
9835   S (mp);
9836
9837   /* Use a control ping for synchronization */
9838   MPING (CONTROL_PING, mp_ping);
9839   S (mp_ping);
9840
9841   W (ret);
9842   return ret;
9843 }
9844
9845 static void vl_api_ip6nd_proxy_details_t_handler
9846   (vl_api_ip6nd_proxy_details_t * mp)
9847 {
9848   vat_main_t *vam = &vat_main;
9849
9850   print (vam->ofp, "host %U sw_if_index %d",
9851          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9852 }
9853
9854 static void vl_api_ip6nd_proxy_details_t_handler_json
9855   (vl_api_ip6nd_proxy_details_t * mp)
9856 {
9857   vat_main_t *vam = &vat_main;
9858   struct in6_addr ip6;
9859   vat_json_node_t *node = NULL;
9860
9861   if (VAT_JSON_ARRAY != vam->json_tree.type)
9862     {
9863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9864       vat_json_init_array (&vam->json_tree);
9865     }
9866   node = vat_json_array_add (&vam->json_tree);
9867
9868   vat_json_init_object (node);
9869   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9870
9871   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9872   vat_json_object_add_ip6 (node, "host", ip6);
9873 }
9874
9875 static int
9876 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9877 {
9878   unformat_input_t *i = vam->input;
9879   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9880   u32 sw_if_index;
9881   u8 sw_if_index_set = 0;
9882   u8 v6_address_set = 0;
9883   vl_api_prefix_t pfx;
9884   u8 use_default = 0;
9885   u8 no_advertise = 0;
9886   u8 off_link = 0;
9887   u8 no_autoconfig = 0;
9888   u8 no_onlink = 0;
9889   u8 is_no = 0;
9890   u32 val_lifetime = 0;
9891   u32 pref_lifetime = 0;
9892   int ret;
9893
9894   /* Parse args required to build the message */
9895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9896     {
9897       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9898         sw_if_index_set = 1;
9899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9902         v6_address_set = 1;
9903       else if (unformat (i, "val_life %d", &val_lifetime))
9904         ;
9905       else if (unformat (i, "pref_life %d", &pref_lifetime))
9906         ;
9907       else if (unformat (i, "def"))
9908         use_default = 1;
9909       else if (unformat (i, "noadv"))
9910         no_advertise = 1;
9911       else if (unformat (i, "offl"))
9912         off_link = 1;
9913       else if (unformat (i, "noauto"))
9914         no_autoconfig = 1;
9915       else if (unformat (i, "nolink"))
9916         no_onlink = 1;
9917       else if (unformat (i, "isno"))
9918         is_no = 1;
9919       else
9920         {
9921           clib_warning ("parse error '%U'", format_unformat_error, i);
9922           return -99;
9923         }
9924     }
9925
9926   if (sw_if_index_set == 0)
9927     {
9928       errmsg ("missing interface name or sw_if_index");
9929       return -99;
9930     }
9931   if (!v6_address_set)
9932     {
9933       errmsg ("no address set");
9934       return -99;
9935     }
9936
9937   /* Construct the API message */
9938   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9939
9940   mp->sw_if_index = ntohl (sw_if_index);
9941   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9942   mp->use_default = use_default;
9943   mp->no_advertise = no_advertise;
9944   mp->off_link = off_link;
9945   mp->no_autoconfig = no_autoconfig;
9946   mp->no_onlink = no_onlink;
9947   mp->is_no = is_no;
9948   mp->val_lifetime = ntohl (val_lifetime);
9949   mp->pref_lifetime = ntohl (pref_lifetime);
9950
9951   /* send it... */
9952   S (mp);
9953
9954   /* Wait for a reply, return good/bad news  */
9955   W (ret);
9956   return ret;
9957 }
9958
9959 static int
9960 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9961 {
9962   unformat_input_t *i = vam->input;
9963   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9964   u32 sw_if_index;
9965   u8 sw_if_index_set = 0;
9966   u8 suppress = 0;
9967   u8 managed = 0;
9968   u8 other = 0;
9969   u8 ll_option = 0;
9970   u8 send_unicast = 0;
9971   u8 cease = 0;
9972   u8 is_no = 0;
9973   u8 default_router = 0;
9974   u32 max_interval = 0;
9975   u32 min_interval = 0;
9976   u32 lifetime = 0;
9977   u32 initial_count = 0;
9978   u32 initial_interval = 0;
9979   int ret;
9980
9981
9982   /* Parse args required to build the message */
9983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9984     {
9985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9986         sw_if_index_set = 1;
9987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9988         sw_if_index_set = 1;
9989       else if (unformat (i, "maxint %d", &max_interval))
9990         ;
9991       else if (unformat (i, "minint %d", &min_interval))
9992         ;
9993       else if (unformat (i, "life %d", &lifetime))
9994         ;
9995       else if (unformat (i, "count %d", &initial_count))
9996         ;
9997       else if (unformat (i, "interval %d", &initial_interval))
9998         ;
9999       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10000         suppress = 1;
10001       else if (unformat (i, "managed"))
10002         managed = 1;
10003       else if (unformat (i, "other"))
10004         other = 1;
10005       else if (unformat (i, "ll"))
10006         ll_option = 1;
10007       else if (unformat (i, "send"))
10008         send_unicast = 1;
10009       else if (unformat (i, "cease"))
10010         cease = 1;
10011       else if (unformat (i, "isno"))
10012         is_no = 1;
10013       else if (unformat (i, "def"))
10014         default_router = 1;
10015       else
10016         {
10017           clib_warning ("parse error '%U'", format_unformat_error, i);
10018           return -99;
10019         }
10020     }
10021
10022   if (sw_if_index_set == 0)
10023     {
10024       errmsg ("missing interface name or sw_if_index");
10025       return -99;
10026     }
10027
10028   /* Construct the API message */
10029   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10030
10031   mp->sw_if_index = ntohl (sw_if_index);
10032   mp->max_interval = ntohl (max_interval);
10033   mp->min_interval = ntohl (min_interval);
10034   mp->lifetime = ntohl (lifetime);
10035   mp->initial_count = ntohl (initial_count);
10036   mp->initial_interval = ntohl (initial_interval);
10037   mp->suppress = suppress;
10038   mp->managed = managed;
10039   mp->other = other;
10040   mp->ll_option = ll_option;
10041   mp->send_unicast = send_unicast;
10042   mp->cease = cease;
10043   mp->is_no = is_no;
10044   mp->default_router = default_router;
10045
10046   /* send it... */
10047   S (mp);
10048
10049   /* Wait for a reply, return good/bad news  */
10050   W (ret);
10051   return ret;
10052 }
10053
10054 static int
10055 api_set_arp_neighbor_limit (vat_main_t * vam)
10056 {
10057   unformat_input_t *i = vam->input;
10058   vl_api_set_arp_neighbor_limit_t *mp;
10059   u32 arp_nbr_limit;
10060   u8 limit_set = 0;
10061   u8 is_ipv6 = 0;
10062   int ret;
10063
10064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10065     {
10066       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10067         limit_set = 1;
10068       else if (unformat (i, "ipv6"))
10069         is_ipv6 = 1;
10070       else
10071         {
10072           clib_warning ("parse error '%U'", format_unformat_error, i);
10073           return -99;
10074         }
10075     }
10076
10077   if (limit_set == 0)
10078     {
10079       errmsg ("missing limit value");
10080       return -99;
10081     }
10082
10083   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10084
10085   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10086   mp->is_ipv6 = is_ipv6;
10087
10088   S (mp);
10089   W (ret);
10090   return ret;
10091 }
10092
10093 static int
10094 api_l2_patch_add_del (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_l2_patch_add_del_t *mp;
10098   u32 rx_sw_if_index;
10099   u8 rx_sw_if_index_set = 0;
10100   u32 tx_sw_if_index;
10101   u8 tx_sw_if_index_set = 0;
10102   u8 is_add = 1;
10103   int ret;
10104
10105   /* Parse args required to build the message */
10106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10107     {
10108       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10109         rx_sw_if_index_set = 1;
10110       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10111         tx_sw_if_index_set = 1;
10112       else if (unformat (i, "rx"))
10113         {
10114           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10115             {
10116               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10117                             &rx_sw_if_index))
10118                 rx_sw_if_index_set = 1;
10119             }
10120           else
10121             break;
10122         }
10123       else if (unformat (i, "tx"))
10124         {
10125           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10126             {
10127               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10128                             &tx_sw_if_index))
10129                 tx_sw_if_index_set = 1;
10130             }
10131           else
10132             break;
10133         }
10134       else if (unformat (i, "del"))
10135         is_add = 0;
10136       else
10137         break;
10138     }
10139
10140   if (rx_sw_if_index_set == 0)
10141     {
10142       errmsg ("missing rx interface name or rx_sw_if_index");
10143       return -99;
10144     }
10145
10146   if (tx_sw_if_index_set == 0)
10147     {
10148       errmsg ("missing tx interface name or tx_sw_if_index");
10149       return -99;
10150     }
10151
10152   M (L2_PATCH_ADD_DEL, mp);
10153
10154   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10155   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10156   mp->is_add = is_add;
10157
10158   S (mp);
10159   W (ret);
10160   return ret;
10161 }
10162
10163 u8 is_del;
10164 u8 localsid_addr[16];
10165 u8 end_psp;
10166 u8 behavior;
10167 u32 sw_if_index;
10168 u32 vlan_index;
10169 u32 fib_table;
10170 u8 nh_addr[16];
10171
10172 static int
10173 api_sr_localsid_add_del (vat_main_t * vam)
10174 {
10175   unformat_input_t *i = vam->input;
10176   vl_api_sr_localsid_add_del_t *mp;
10177
10178   u8 is_del;
10179   ip6_address_t localsid;
10180   u8 end_psp = 0;
10181   u8 behavior = ~0;
10182   u32 sw_if_index;
10183   u32 fib_table = ~(u32) 0;
10184   ip6_address_t nh_addr6;
10185   ip4_address_t nh_addr4;
10186   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10187   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10188
10189   bool nexthop_set = 0;
10190
10191   int ret;
10192
10193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10194     {
10195       if (unformat (i, "del"))
10196         is_del = 1;
10197       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10198       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10199         nexthop_set = 1;
10200       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10201         nexthop_set = 1;
10202       else if (unformat (i, "behavior %u", &behavior));
10203       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10204       else if (unformat (i, "fib-table %u", &fib_table));
10205       else if (unformat (i, "end.psp %u", &behavior));
10206       else
10207         break;
10208     }
10209
10210   M (SR_LOCALSID_ADD_DEL, mp);
10211
10212   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10213   if (nexthop_set)
10214     {
10215       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10216       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10217     }
10218   mp->behavior = behavior;
10219   mp->sw_if_index = ntohl (sw_if_index);
10220   mp->fib_table = ntohl (fib_table);
10221   mp->end_psp = end_psp;
10222   mp->is_del = is_del;
10223
10224   S (mp);
10225   W (ret);
10226   return ret;
10227 }
10228
10229 static int
10230 api_ioam_enable (vat_main_t * vam)
10231 {
10232   unformat_input_t *input = vam->input;
10233   vl_api_ioam_enable_t *mp;
10234   u32 id = 0;
10235   int has_trace_option = 0;
10236   int has_pot_option = 0;
10237   int has_seqno_option = 0;
10238   int has_analyse_option = 0;
10239   int ret;
10240
10241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10242     {
10243       if (unformat (input, "trace"))
10244         has_trace_option = 1;
10245       else if (unformat (input, "pot"))
10246         has_pot_option = 1;
10247       else if (unformat (input, "seqno"))
10248         has_seqno_option = 1;
10249       else if (unformat (input, "analyse"))
10250         has_analyse_option = 1;
10251       else
10252         break;
10253     }
10254   M (IOAM_ENABLE, mp);
10255   mp->id = htons (id);
10256   mp->seqno = has_seqno_option;
10257   mp->analyse = has_analyse_option;
10258   mp->pot_enable = has_pot_option;
10259   mp->trace_enable = has_trace_option;
10260
10261   S (mp);
10262   W (ret);
10263   return ret;
10264 }
10265
10266
10267 static int
10268 api_ioam_disable (vat_main_t * vam)
10269 {
10270   vl_api_ioam_disable_t *mp;
10271   int ret;
10272
10273   M (IOAM_DISABLE, mp);
10274   S (mp);
10275   W (ret);
10276   return ret;
10277 }
10278
10279 #define foreach_tcp_proto_field                 \
10280 _(src_port)                                     \
10281 _(dst_port)
10282
10283 #define foreach_udp_proto_field                 \
10284 _(src_port)                                     \
10285 _(dst_port)
10286
10287 #define foreach_ip4_proto_field                 \
10288 _(src_address)                                  \
10289 _(dst_address)                                  \
10290 _(tos)                                          \
10291 _(length)                                       \
10292 _(fragment_id)                                  \
10293 _(ttl)                                          \
10294 _(protocol)                                     \
10295 _(checksum)
10296
10297 typedef struct
10298 {
10299   u16 src_port, dst_port;
10300 } tcpudp_header_t;
10301
10302 #if VPP_API_TEST_BUILTIN == 0
10303 uword
10304 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10305 {
10306   u8 **maskp = va_arg (*args, u8 **);
10307   u8 *mask = 0;
10308   u8 found_something = 0;
10309   tcp_header_t *tcp;
10310
10311 #define _(a) u8 a=0;
10312   foreach_tcp_proto_field;
10313 #undef _
10314
10315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10316     {
10317       if (0);
10318 #define _(a) else if (unformat (input, #a)) a=1;
10319       foreach_tcp_proto_field
10320 #undef _
10321         else
10322         break;
10323     }
10324
10325 #define _(a) found_something += a;
10326   foreach_tcp_proto_field;
10327 #undef _
10328
10329   if (found_something == 0)
10330     return 0;
10331
10332   vec_validate (mask, sizeof (*tcp) - 1);
10333
10334   tcp = (tcp_header_t *) mask;
10335
10336 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10337   foreach_tcp_proto_field;
10338 #undef _
10339
10340   *maskp = mask;
10341   return 1;
10342 }
10343
10344 uword
10345 unformat_udp_mask (unformat_input_t * input, va_list * args)
10346 {
10347   u8 **maskp = va_arg (*args, u8 **);
10348   u8 *mask = 0;
10349   u8 found_something = 0;
10350   udp_header_t *udp;
10351
10352 #define _(a) u8 a=0;
10353   foreach_udp_proto_field;
10354 #undef _
10355
10356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10357     {
10358       if (0);
10359 #define _(a) else if (unformat (input, #a)) a=1;
10360       foreach_udp_proto_field
10361 #undef _
10362         else
10363         break;
10364     }
10365
10366 #define _(a) found_something += a;
10367   foreach_udp_proto_field;
10368 #undef _
10369
10370   if (found_something == 0)
10371     return 0;
10372
10373   vec_validate (mask, sizeof (*udp) - 1);
10374
10375   udp = (udp_header_t *) mask;
10376
10377 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10378   foreach_udp_proto_field;
10379 #undef _
10380
10381   *maskp = mask;
10382   return 1;
10383 }
10384
10385 uword
10386 unformat_l4_mask (unformat_input_t * input, va_list * args)
10387 {
10388   u8 **maskp = va_arg (*args, u8 **);
10389   u16 src_port = 0, dst_port = 0;
10390   tcpudp_header_t *tcpudp;
10391
10392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10393     {
10394       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10395         return 1;
10396       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10397         return 1;
10398       else if (unformat (input, "src_port"))
10399         src_port = 0xFFFF;
10400       else if (unformat (input, "dst_port"))
10401         dst_port = 0xFFFF;
10402       else
10403         return 0;
10404     }
10405
10406   if (!src_port && !dst_port)
10407     return 0;
10408
10409   u8 *mask = 0;
10410   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10411
10412   tcpudp = (tcpudp_header_t *) mask;
10413   tcpudp->src_port = src_port;
10414   tcpudp->dst_port = dst_port;
10415
10416   *maskp = mask;
10417
10418   return 1;
10419 }
10420
10421 uword
10422 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10423 {
10424   u8 **maskp = va_arg (*args, u8 **);
10425   u8 *mask = 0;
10426   u8 found_something = 0;
10427   ip4_header_t *ip;
10428
10429 #define _(a) u8 a=0;
10430   foreach_ip4_proto_field;
10431 #undef _
10432   u8 version = 0;
10433   u8 hdr_length = 0;
10434
10435
10436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10437     {
10438       if (unformat (input, "version"))
10439         version = 1;
10440       else if (unformat (input, "hdr_length"))
10441         hdr_length = 1;
10442       else if (unformat (input, "src"))
10443         src_address = 1;
10444       else if (unformat (input, "dst"))
10445         dst_address = 1;
10446       else if (unformat (input, "proto"))
10447         protocol = 1;
10448
10449 #define _(a) else if (unformat (input, #a)) a=1;
10450       foreach_ip4_proto_field
10451 #undef _
10452         else
10453         break;
10454     }
10455
10456 #define _(a) found_something += a;
10457   foreach_ip4_proto_field;
10458 #undef _
10459
10460   if (found_something == 0)
10461     return 0;
10462
10463   vec_validate (mask, sizeof (*ip) - 1);
10464
10465   ip = (ip4_header_t *) mask;
10466
10467 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10468   foreach_ip4_proto_field;
10469 #undef _
10470
10471   ip->ip_version_and_header_length = 0;
10472
10473   if (version)
10474     ip->ip_version_and_header_length |= 0xF0;
10475
10476   if (hdr_length)
10477     ip->ip_version_and_header_length |= 0x0F;
10478
10479   *maskp = mask;
10480   return 1;
10481 }
10482
10483 #define foreach_ip6_proto_field                 \
10484 _(src_address)                                  \
10485 _(dst_address)                                  \
10486 _(payload_length)                               \
10487 _(hop_limit)                                    \
10488 _(protocol)
10489
10490 uword
10491 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10492 {
10493   u8 **maskp = va_arg (*args, u8 **);
10494   u8 *mask = 0;
10495   u8 found_something = 0;
10496   ip6_header_t *ip;
10497   u32 ip_version_traffic_class_and_flow_label;
10498
10499 #define _(a) u8 a=0;
10500   foreach_ip6_proto_field;
10501 #undef _
10502   u8 version = 0;
10503   u8 traffic_class = 0;
10504   u8 flow_label = 0;
10505
10506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10507     {
10508       if (unformat (input, "version"))
10509         version = 1;
10510       else if (unformat (input, "traffic-class"))
10511         traffic_class = 1;
10512       else if (unformat (input, "flow-label"))
10513         flow_label = 1;
10514       else if (unformat (input, "src"))
10515         src_address = 1;
10516       else if (unformat (input, "dst"))
10517         dst_address = 1;
10518       else if (unformat (input, "proto"))
10519         protocol = 1;
10520
10521 #define _(a) else if (unformat (input, #a)) a=1;
10522       foreach_ip6_proto_field
10523 #undef _
10524         else
10525         break;
10526     }
10527
10528 #define _(a) found_something += a;
10529   foreach_ip6_proto_field;
10530 #undef _
10531
10532   if (found_something == 0)
10533     return 0;
10534
10535   vec_validate (mask, sizeof (*ip) - 1);
10536
10537   ip = (ip6_header_t *) mask;
10538
10539 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10540   foreach_ip6_proto_field;
10541 #undef _
10542
10543   ip_version_traffic_class_and_flow_label = 0;
10544
10545   if (version)
10546     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10547
10548   if (traffic_class)
10549     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10550
10551   if (flow_label)
10552     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10553
10554   ip->ip_version_traffic_class_and_flow_label =
10555     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10556
10557   *maskp = mask;
10558   return 1;
10559 }
10560
10561 uword
10562 unformat_l3_mask (unformat_input_t * input, va_list * args)
10563 {
10564   u8 **maskp = va_arg (*args, u8 **);
10565
10566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10567     {
10568       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10569         return 1;
10570       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10571         return 1;
10572       else
10573         break;
10574     }
10575   return 0;
10576 }
10577
10578 uword
10579 unformat_l2_mask (unformat_input_t * input, va_list * args)
10580 {
10581   u8 **maskp = va_arg (*args, u8 **);
10582   u8 *mask = 0;
10583   u8 src = 0;
10584   u8 dst = 0;
10585   u8 proto = 0;
10586   u8 tag1 = 0;
10587   u8 tag2 = 0;
10588   u8 ignore_tag1 = 0;
10589   u8 ignore_tag2 = 0;
10590   u8 cos1 = 0;
10591   u8 cos2 = 0;
10592   u8 dot1q = 0;
10593   u8 dot1ad = 0;
10594   int len = 14;
10595
10596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10597     {
10598       if (unformat (input, "src"))
10599         src = 1;
10600       else if (unformat (input, "dst"))
10601         dst = 1;
10602       else if (unformat (input, "proto"))
10603         proto = 1;
10604       else if (unformat (input, "tag1"))
10605         tag1 = 1;
10606       else if (unformat (input, "tag2"))
10607         tag2 = 1;
10608       else if (unformat (input, "ignore-tag1"))
10609         ignore_tag1 = 1;
10610       else if (unformat (input, "ignore-tag2"))
10611         ignore_tag2 = 1;
10612       else if (unformat (input, "cos1"))
10613         cos1 = 1;
10614       else if (unformat (input, "cos2"))
10615         cos2 = 1;
10616       else if (unformat (input, "dot1q"))
10617         dot1q = 1;
10618       else if (unformat (input, "dot1ad"))
10619         dot1ad = 1;
10620       else
10621         break;
10622     }
10623   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10624        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10625     return 0;
10626
10627   if (tag1 || ignore_tag1 || cos1 || dot1q)
10628     len = 18;
10629   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10630     len = 22;
10631
10632   vec_validate (mask, len - 1);
10633
10634   if (dst)
10635     clib_memset (mask, 0xff, 6);
10636
10637   if (src)
10638     clib_memset (mask + 6, 0xff, 6);
10639
10640   if (tag2 || dot1ad)
10641     {
10642       /* inner vlan tag */
10643       if (tag2)
10644         {
10645           mask[19] = 0xff;
10646           mask[18] = 0x0f;
10647         }
10648       if (cos2)
10649         mask[18] |= 0xe0;
10650       if (proto)
10651         mask[21] = mask[20] = 0xff;
10652       if (tag1)
10653         {
10654           mask[15] = 0xff;
10655           mask[14] = 0x0f;
10656         }
10657       if (cos1)
10658         mask[14] |= 0xe0;
10659       *maskp = mask;
10660       return 1;
10661     }
10662   if (tag1 | dot1q)
10663     {
10664       if (tag1)
10665         {
10666           mask[15] = 0xff;
10667           mask[14] = 0x0f;
10668         }
10669       if (cos1)
10670         mask[14] |= 0xe0;
10671       if (proto)
10672         mask[16] = mask[17] = 0xff;
10673
10674       *maskp = mask;
10675       return 1;
10676     }
10677   if (cos2)
10678     mask[18] |= 0xe0;
10679   if (cos1)
10680     mask[14] |= 0xe0;
10681   if (proto)
10682     mask[12] = mask[13] = 0xff;
10683
10684   *maskp = mask;
10685   return 1;
10686 }
10687
10688 uword
10689 unformat_classify_mask (unformat_input_t * input, va_list * args)
10690 {
10691   u8 **maskp = va_arg (*args, u8 **);
10692   u32 *skipp = va_arg (*args, u32 *);
10693   u32 *matchp = va_arg (*args, u32 *);
10694   u32 match;
10695   u8 *mask = 0;
10696   u8 *l2 = 0;
10697   u8 *l3 = 0;
10698   u8 *l4 = 0;
10699   int i;
10700
10701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10704         ;
10705       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10706         ;
10707       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10708         ;
10709       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10710         ;
10711       else
10712         break;
10713     }
10714
10715   if (l4 && !l3)
10716     {
10717       vec_free (mask);
10718       vec_free (l2);
10719       vec_free (l4);
10720       return 0;
10721     }
10722
10723   if (mask || l2 || l3 || l4)
10724     {
10725       if (l2 || l3 || l4)
10726         {
10727           /* "With a free Ethernet header in every package" */
10728           if (l2 == 0)
10729             vec_validate (l2, 13);
10730           mask = l2;
10731           if (vec_len (l3))
10732             {
10733               vec_append (mask, l3);
10734               vec_free (l3);
10735             }
10736           if (vec_len (l4))
10737             {
10738               vec_append (mask, l4);
10739               vec_free (l4);
10740             }
10741         }
10742
10743       /* Scan forward looking for the first significant mask octet */
10744       for (i = 0; i < vec_len (mask); i++)
10745         if (mask[i])
10746           break;
10747
10748       /* compute (skip, match) params */
10749       *skipp = i / sizeof (u32x4);
10750       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10751
10752       /* Pad mask to an even multiple of the vector size */
10753       while (vec_len (mask) % sizeof (u32x4))
10754         vec_add1 (mask, 0);
10755
10756       match = vec_len (mask) / sizeof (u32x4);
10757
10758       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10759         {
10760           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10761           if (*tmp || *(tmp + 1))
10762             break;
10763           match--;
10764         }
10765       if (match == 0)
10766         clib_warning ("BUG: match 0");
10767
10768       _vec_len (mask) = match * sizeof (u32x4);
10769
10770       *matchp = match;
10771       *maskp = mask;
10772
10773       return 1;
10774     }
10775
10776   return 0;
10777 }
10778 #endif /* VPP_API_TEST_BUILTIN */
10779
10780 #define foreach_l2_next                         \
10781 _(drop, DROP)                                   \
10782 _(ethernet, ETHERNET_INPUT)                     \
10783 _(ip4, IP4_INPUT)                               \
10784 _(ip6, IP6_INPUT)
10785
10786 uword
10787 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10788 {
10789   u32 *miss_next_indexp = va_arg (*args, u32 *);
10790   u32 next_index = 0;
10791   u32 tmp;
10792
10793 #define _(n,N) \
10794   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10795   foreach_l2_next;
10796 #undef _
10797
10798   if (unformat (input, "%d", &tmp))
10799     {
10800       next_index = tmp;
10801       goto out;
10802     }
10803
10804   return 0;
10805
10806 out:
10807   *miss_next_indexp = next_index;
10808   return 1;
10809 }
10810
10811 #define foreach_ip_next                         \
10812 _(drop, DROP)                                   \
10813 _(local, LOCAL)                                 \
10814 _(rewrite, REWRITE)
10815
10816 uword
10817 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10818 {
10819   u32 *miss_next_indexp = va_arg (*args, u32 *);
10820   u32 next_index = 0;
10821   u32 tmp;
10822
10823 #define _(n,N) \
10824   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10825   foreach_ip_next;
10826 #undef _
10827
10828   if (unformat (input, "%d", &tmp))
10829     {
10830       next_index = tmp;
10831       goto out;
10832     }
10833
10834   return 0;
10835
10836 out:
10837   *miss_next_indexp = next_index;
10838   return 1;
10839 }
10840
10841 #define foreach_acl_next                        \
10842 _(deny, DENY)
10843
10844 uword
10845 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10846 {
10847   u32 *miss_next_indexp = va_arg (*args, u32 *);
10848   u32 next_index = 0;
10849   u32 tmp;
10850
10851 #define _(n,N) \
10852   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10853   foreach_acl_next;
10854 #undef _
10855
10856   if (unformat (input, "permit"))
10857     {
10858       next_index = ~0;
10859       goto out;
10860     }
10861   else if (unformat (input, "%d", &tmp))
10862     {
10863       next_index = tmp;
10864       goto out;
10865     }
10866
10867   return 0;
10868
10869 out:
10870   *miss_next_indexp = next_index;
10871   return 1;
10872 }
10873
10874 uword
10875 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10876 {
10877   u32 *r = va_arg (*args, u32 *);
10878
10879   if (unformat (input, "conform-color"))
10880     *r = POLICE_CONFORM;
10881   else if (unformat (input, "exceed-color"))
10882     *r = POLICE_EXCEED;
10883   else
10884     return 0;
10885
10886   return 1;
10887 }
10888
10889 static int
10890 api_classify_add_del_table (vat_main_t * vam)
10891 {
10892   unformat_input_t *i = vam->input;
10893   vl_api_classify_add_del_table_t *mp;
10894
10895   u32 nbuckets = 2;
10896   u32 skip = ~0;
10897   u32 match = ~0;
10898   int is_add = 1;
10899   int del_chain = 0;
10900   u32 table_index = ~0;
10901   u32 next_table_index = ~0;
10902   u32 miss_next_index = ~0;
10903   u32 memory_size = 32 << 20;
10904   u8 *mask = 0;
10905   u32 current_data_flag = 0;
10906   int current_data_offset = 0;
10907   int ret;
10908
10909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10910     {
10911       if (unformat (i, "del"))
10912         is_add = 0;
10913       else if (unformat (i, "del-chain"))
10914         {
10915           is_add = 0;
10916           del_chain = 1;
10917         }
10918       else if (unformat (i, "buckets %d", &nbuckets))
10919         ;
10920       else if (unformat (i, "memory_size %d", &memory_size))
10921         ;
10922       else if (unformat (i, "skip %d", &skip))
10923         ;
10924       else if (unformat (i, "match %d", &match))
10925         ;
10926       else if (unformat (i, "table %d", &table_index))
10927         ;
10928       else if (unformat (i, "mask %U", unformat_classify_mask,
10929                          &mask, &skip, &match))
10930         ;
10931       else if (unformat (i, "next-table %d", &next_table_index))
10932         ;
10933       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10934                          &miss_next_index))
10935         ;
10936       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10937                          &miss_next_index))
10938         ;
10939       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10940                          &miss_next_index))
10941         ;
10942       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10943         ;
10944       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10945         ;
10946       else
10947         break;
10948     }
10949
10950   if (is_add && mask == 0)
10951     {
10952       errmsg ("Mask required");
10953       return -99;
10954     }
10955
10956   if (is_add && skip == ~0)
10957     {
10958       errmsg ("skip count required");
10959       return -99;
10960     }
10961
10962   if (is_add && match == ~0)
10963     {
10964       errmsg ("match count required");
10965       return -99;
10966     }
10967
10968   if (!is_add && table_index == ~0)
10969     {
10970       errmsg ("table index required for delete");
10971       return -99;
10972     }
10973
10974   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10975
10976   mp->is_add = is_add;
10977   mp->del_chain = del_chain;
10978   mp->table_index = ntohl (table_index);
10979   mp->nbuckets = ntohl (nbuckets);
10980   mp->memory_size = ntohl (memory_size);
10981   mp->skip_n_vectors = ntohl (skip);
10982   mp->match_n_vectors = ntohl (match);
10983   mp->next_table_index = ntohl (next_table_index);
10984   mp->miss_next_index = ntohl (miss_next_index);
10985   mp->current_data_flag = ntohl (current_data_flag);
10986   mp->current_data_offset = ntohl (current_data_offset);
10987   mp->mask_len = ntohl (vec_len (mask));
10988   clib_memcpy (mp->mask, mask, vec_len (mask));
10989
10990   vec_free (mask);
10991
10992   S (mp);
10993   W (ret);
10994   return ret;
10995 }
10996
10997 #if VPP_API_TEST_BUILTIN == 0
10998 uword
10999 unformat_l4_match (unformat_input_t * input, va_list * args)
11000 {
11001   u8 **matchp = va_arg (*args, u8 **);
11002
11003   u8 *proto_header = 0;
11004   int src_port = 0;
11005   int dst_port = 0;
11006
11007   tcpudp_header_t h;
11008
11009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11010     {
11011       if (unformat (input, "src_port %d", &src_port))
11012         ;
11013       else if (unformat (input, "dst_port %d", &dst_port))
11014         ;
11015       else
11016         return 0;
11017     }
11018
11019   h.src_port = clib_host_to_net_u16 (src_port);
11020   h.dst_port = clib_host_to_net_u16 (dst_port);
11021   vec_validate (proto_header, sizeof (h) - 1);
11022   memcpy (proto_header, &h, sizeof (h));
11023
11024   *matchp = proto_header;
11025
11026   return 1;
11027 }
11028
11029 uword
11030 unformat_ip4_match (unformat_input_t * input, va_list * args)
11031 {
11032   u8 **matchp = va_arg (*args, u8 **);
11033   u8 *match = 0;
11034   ip4_header_t *ip;
11035   int version = 0;
11036   u32 version_val;
11037   int hdr_length = 0;
11038   u32 hdr_length_val;
11039   int src = 0, dst = 0;
11040   ip4_address_t src_val, dst_val;
11041   int proto = 0;
11042   u32 proto_val;
11043   int tos = 0;
11044   u32 tos_val;
11045   int length = 0;
11046   u32 length_val;
11047   int fragment_id = 0;
11048   u32 fragment_id_val;
11049   int ttl = 0;
11050   int ttl_val;
11051   int checksum = 0;
11052   u32 checksum_val;
11053
11054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11055     {
11056       if (unformat (input, "version %d", &version_val))
11057         version = 1;
11058       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11059         hdr_length = 1;
11060       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11061         src = 1;
11062       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11063         dst = 1;
11064       else if (unformat (input, "proto %d", &proto_val))
11065         proto = 1;
11066       else if (unformat (input, "tos %d", &tos_val))
11067         tos = 1;
11068       else if (unformat (input, "length %d", &length_val))
11069         length = 1;
11070       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11071         fragment_id = 1;
11072       else if (unformat (input, "ttl %d", &ttl_val))
11073         ttl = 1;
11074       else if (unformat (input, "checksum %d", &checksum_val))
11075         checksum = 1;
11076       else
11077         break;
11078     }
11079
11080   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11081       + ttl + checksum == 0)
11082     return 0;
11083
11084   /*
11085    * Aligned because we use the real comparison functions
11086    */
11087   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11088
11089   ip = (ip4_header_t *) match;
11090
11091   /* These are realistically matched in practice */
11092   if (src)
11093     ip->src_address.as_u32 = src_val.as_u32;
11094
11095   if (dst)
11096     ip->dst_address.as_u32 = dst_val.as_u32;
11097
11098   if (proto)
11099     ip->protocol = proto_val;
11100
11101
11102   /* These are not, but they're included for completeness */
11103   if (version)
11104     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11105
11106   if (hdr_length)
11107     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11108
11109   if (tos)
11110     ip->tos = tos_val;
11111
11112   if (length)
11113     ip->length = clib_host_to_net_u16 (length_val);
11114
11115   if (ttl)
11116     ip->ttl = ttl_val;
11117
11118   if (checksum)
11119     ip->checksum = clib_host_to_net_u16 (checksum_val);
11120
11121   *matchp = match;
11122   return 1;
11123 }
11124
11125 uword
11126 unformat_ip6_match (unformat_input_t * input, va_list * args)
11127 {
11128   u8 **matchp = va_arg (*args, u8 **);
11129   u8 *match = 0;
11130   ip6_header_t *ip;
11131   int version = 0;
11132   u32 version_val;
11133   u8 traffic_class = 0;
11134   u32 traffic_class_val = 0;
11135   u8 flow_label = 0;
11136   u8 flow_label_val;
11137   int src = 0, dst = 0;
11138   ip6_address_t src_val, dst_val;
11139   int proto = 0;
11140   u32 proto_val;
11141   int payload_length = 0;
11142   u32 payload_length_val;
11143   int hop_limit = 0;
11144   int hop_limit_val;
11145   u32 ip_version_traffic_class_and_flow_label;
11146
11147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11148     {
11149       if (unformat (input, "version %d", &version_val))
11150         version = 1;
11151       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11152         traffic_class = 1;
11153       else if (unformat (input, "flow_label %d", &flow_label_val))
11154         flow_label = 1;
11155       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11156         src = 1;
11157       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11158         dst = 1;
11159       else if (unformat (input, "proto %d", &proto_val))
11160         proto = 1;
11161       else if (unformat (input, "payload_length %d", &payload_length_val))
11162         payload_length = 1;
11163       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11164         hop_limit = 1;
11165       else
11166         break;
11167     }
11168
11169   if (version + traffic_class + flow_label + src + dst + proto +
11170       payload_length + hop_limit == 0)
11171     return 0;
11172
11173   /*
11174    * Aligned because we use the real comparison functions
11175    */
11176   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11177
11178   ip = (ip6_header_t *) match;
11179
11180   if (src)
11181     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11182
11183   if (dst)
11184     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11185
11186   if (proto)
11187     ip->protocol = proto_val;
11188
11189   ip_version_traffic_class_and_flow_label = 0;
11190
11191   if (version)
11192     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11193
11194   if (traffic_class)
11195     ip_version_traffic_class_and_flow_label |=
11196       (traffic_class_val & 0xFF) << 20;
11197
11198   if (flow_label)
11199     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11200
11201   ip->ip_version_traffic_class_and_flow_label =
11202     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11203
11204   if (payload_length)
11205     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11206
11207   if (hop_limit)
11208     ip->hop_limit = hop_limit_val;
11209
11210   *matchp = match;
11211   return 1;
11212 }
11213
11214 uword
11215 unformat_l3_match (unformat_input_t * input, va_list * args)
11216 {
11217   u8 **matchp = va_arg (*args, u8 **);
11218
11219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11222         return 1;
11223       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11224         return 1;
11225       else
11226         break;
11227     }
11228   return 0;
11229 }
11230
11231 uword
11232 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11233 {
11234   u8 *tagp = va_arg (*args, u8 *);
11235   u32 tag;
11236
11237   if (unformat (input, "%d", &tag))
11238     {
11239       tagp[0] = (tag >> 8) & 0x0F;
11240       tagp[1] = tag & 0xFF;
11241       return 1;
11242     }
11243
11244   return 0;
11245 }
11246
11247 uword
11248 unformat_l2_match (unformat_input_t * input, va_list * args)
11249 {
11250   u8 **matchp = va_arg (*args, u8 **);
11251   u8 *match = 0;
11252   u8 src = 0;
11253   u8 src_val[6];
11254   u8 dst = 0;
11255   u8 dst_val[6];
11256   u8 proto = 0;
11257   u16 proto_val;
11258   u8 tag1 = 0;
11259   u8 tag1_val[2];
11260   u8 tag2 = 0;
11261   u8 tag2_val[2];
11262   int len = 14;
11263   u8 ignore_tag1 = 0;
11264   u8 ignore_tag2 = 0;
11265   u8 cos1 = 0;
11266   u8 cos2 = 0;
11267   u32 cos1_val = 0;
11268   u32 cos2_val = 0;
11269
11270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11271     {
11272       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11273         src = 1;
11274       else
11275         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11276         dst = 1;
11277       else if (unformat (input, "proto %U",
11278                          unformat_ethernet_type_host_byte_order, &proto_val))
11279         proto = 1;
11280       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11281         tag1 = 1;
11282       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11283         tag2 = 1;
11284       else if (unformat (input, "ignore-tag1"))
11285         ignore_tag1 = 1;
11286       else if (unformat (input, "ignore-tag2"))
11287         ignore_tag2 = 1;
11288       else if (unformat (input, "cos1 %d", &cos1_val))
11289         cos1 = 1;
11290       else if (unformat (input, "cos2 %d", &cos2_val))
11291         cos2 = 1;
11292       else
11293         break;
11294     }
11295   if ((src + dst + proto + tag1 + tag2 +
11296        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11297     return 0;
11298
11299   if (tag1 || ignore_tag1 || cos1)
11300     len = 18;
11301   if (tag2 || ignore_tag2 || cos2)
11302     len = 22;
11303
11304   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11305
11306   if (dst)
11307     clib_memcpy (match, dst_val, 6);
11308
11309   if (src)
11310     clib_memcpy (match + 6, src_val, 6);
11311
11312   if (tag2)
11313     {
11314       /* inner vlan tag */
11315       match[19] = tag2_val[1];
11316       match[18] = tag2_val[0];
11317       if (cos2)
11318         match[18] |= (cos2_val & 0x7) << 5;
11319       if (proto)
11320         {
11321           match[21] = proto_val & 0xff;
11322           match[20] = proto_val >> 8;
11323         }
11324       if (tag1)
11325         {
11326           match[15] = tag1_val[1];
11327           match[14] = tag1_val[0];
11328         }
11329       if (cos1)
11330         match[14] |= (cos1_val & 0x7) << 5;
11331       *matchp = match;
11332       return 1;
11333     }
11334   if (tag1)
11335     {
11336       match[15] = tag1_val[1];
11337       match[14] = tag1_val[0];
11338       if (proto)
11339         {
11340           match[17] = proto_val & 0xff;
11341           match[16] = proto_val >> 8;
11342         }
11343       if (cos1)
11344         match[14] |= (cos1_val & 0x7) << 5;
11345
11346       *matchp = match;
11347       return 1;
11348     }
11349   if (cos2)
11350     match[18] |= (cos2_val & 0x7) << 5;
11351   if (cos1)
11352     match[14] |= (cos1_val & 0x7) << 5;
11353   if (proto)
11354     {
11355       match[13] = proto_val & 0xff;
11356       match[12] = proto_val >> 8;
11357     }
11358
11359   *matchp = match;
11360   return 1;
11361 }
11362
11363 uword
11364 unformat_qos_source (unformat_input_t * input, va_list * args)
11365 {
11366   int *qs = va_arg (*args, int *);
11367
11368   if (unformat (input, "ip"))
11369     *qs = QOS_SOURCE_IP;
11370   else if (unformat (input, "mpls"))
11371     *qs = QOS_SOURCE_MPLS;
11372   else if (unformat (input, "ext"))
11373     *qs = QOS_SOURCE_EXT;
11374   else if (unformat (input, "vlan"))
11375     *qs = QOS_SOURCE_VLAN;
11376   else
11377     return 0;
11378
11379   return 1;
11380 }
11381 #endif
11382
11383 uword
11384 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11385 {
11386   u8 **matchp = va_arg (*args, u8 **);
11387   u32 skip_n_vectors = va_arg (*args, u32);
11388   u32 match_n_vectors = va_arg (*args, u32);
11389
11390   u8 *match = 0;
11391   u8 *l2 = 0;
11392   u8 *l3 = 0;
11393   u8 *l4 = 0;
11394
11395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11396     {
11397       if (unformat (input, "hex %U", unformat_hex_string, &match))
11398         ;
11399       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11400         ;
11401       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11402         ;
11403       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11404         ;
11405       else
11406         break;
11407     }
11408
11409   if (l4 && !l3)
11410     {
11411       vec_free (match);
11412       vec_free (l2);
11413       vec_free (l4);
11414       return 0;
11415     }
11416
11417   if (match || l2 || l3 || l4)
11418     {
11419       if (l2 || l3 || l4)
11420         {
11421           /* "Win a free Ethernet header in every packet" */
11422           if (l2 == 0)
11423             vec_validate_aligned (l2, 13, sizeof (u32x4));
11424           match = l2;
11425           if (vec_len (l3))
11426             {
11427               vec_append_aligned (match, l3, sizeof (u32x4));
11428               vec_free (l3);
11429             }
11430           if (vec_len (l4))
11431             {
11432               vec_append_aligned (match, l4, sizeof (u32x4));
11433               vec_free (l4);
11434             }
11435         }
11436
11437       /* Make sure the vector is big enough even if key is all 0's */
11438       vec_validate_aligned
11439         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11440          sizeof (u32x4));
11441
11442       /* Set size, include skipped vectors */
11443       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11444
11445       *matchp = match;
11446
11447       return 1;
11448     }
11449
11450   return 0;
11451 }
11452
11453 static int
11454 api_classify_add_del_session (vat_main_t * vam)
11455 {
11456   unformat_input_t *i = vam->input;
11457   vl_api_classify_add_del_session_t *mp;
11458   int is_add = 1;
11459   u32 table_index = ~0;
11460   u32 hit_next_index = ~0;
11461   u32 opaque_index = ~0;
11462   u8 *match = 0;
11463   i32 advance = 0;
11464   u32 skip_n_vectors = 0;
11465   u32 match_n_vectors = 0;
11466   u32 action = 0;
11467   u32 metadata = 0;
11468   int ret;
11469
11470   /*
11471    * Warning: you have to supply skip_n and match_n
11472    * because the API client cant simply look at the classify
11473    * table object.
11474    */
11475
11476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11477     {
11478       if (unformat (i, "del"))
11479         is_add = 0;
11480       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11481                          &hit_next_index))
11482         ;
11483       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11484                          &hit_next_index))
11485         ;
11486       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11487                          &hit_next_index))
11488         ;
11489       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11490         ;
11491       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11492         ;
11493       else if (unformat (i, "opaque-index %d", &opaque_index))
11494         ;
11495       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11496         ;
11497       else if (unformat (i, "match_n %d", &match_n_vectors))
11498         ;
11499       else if (unformat (i, "match %U", api_unformat_classify_match,
11500                          &match, skip_n_vectors, match_n_vectors))
11501         ;
11502       else if (unformat (i, "advance %d", &advance))
11503         ;
11504       else if (unformat (i, "table-index %d", &table_index))
11505         ;
11506       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11507         action = 1;
11508       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11509         action = 2;
11510       else if (unformat (i, "action %d", &action))
11511         ;
11512       else if (unformat (i, "metadata %d", &metadata))
11513         ;
11514       else
11515         break;
11516     }
11517
11518   if (table_index == ~0)
11519     {
11520       errmsg ("Table index required");
11521       return -99;
11522     }
11523
11524   if (is_add && match == 0)
11525     {
11526       errmsg ("Match value required");
11527       return -99;
11528     }
11529
11530   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11531
11532   mp->is_add = is_add;
11533   mp->table_index = ntohl (table_index);
11534   mp->hit_next_index = ntohl (hit_next_index);
11535   mp->opaque_index = ntohl (opaque_index);
11536   mp->advance = ntohl (advance);
11537   mp->action = action;
11538   mp->metadata = ntohl (metadata);
11539   mp->match_len = ntohl (vec_len (match));
11540   clib_memcpy (mp->match, match, vec_len (match));
11541   vec_free (match);
11542
11543   S (mp);
11544   W (ret);
11545   return ret;
11546 }
11547
11548 static int
11549 api_classify_set_interface_ip_table (vat_main_t * vam)
11550 {
11551   unformat_input_t *i = vam->input;
11552   vl_api_classify_set_interface_ip_table_t *mp;
11553   u32 sw_if_index;
11554   int sw_if_index_set;
11555   u32 table_index = ~0;
11556   u8 is_ipv6 = 0;
11557   int ret;
11558
11559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11560     {
11561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11562         sw_if_index_set = 1;
11563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11564         sw_if_index_set = 1;
11565       else if (unformat (i, "table %d", &table_index))
11566         ;
11567       else
11568         {
11569           clib_warning ("parse error '%U'", format_unformat_error, i);
11570           return -99;
11571         }
11572     }
11573
11574   if (sw_if_index_set == 0)
11575     {
11576       errmsg ("missing interface name or sw_if_index");
11577       return -99;
11578     }
11579
11580
11581   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11582
11583   mp->sw_if_index = ntohl (sw_if_index);
11584   mp->table_index = ntohl (table_index);
11585   mp->is_ipv6 = is_ipv6;
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_classify_set_interface_l2_tables (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   vl_api_classify_set_interface_l2_tables_t *mp;
11597   u32 sw_if_index;
11598   int sw_if_index_set;
11599   u32 ip4_table_index = ~0;
11600   u32 ip6_table_index = ~0;
11601   u32 other_table_index = ~0;
11602   u32 is_input = 1;
11603   int ret;
11604
11605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11606     {
11607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11610         sw_if_index_set = 1;
11611       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11612         ;
11613       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11614         ;
11615       else if (unformat (i, "other-table %d", &other_table_index))
11616         ;
11617       else if (unformat (i, "is-input %d", &is_input))
11618         ;
11619       else
11620         {
11621           clib_warning ("parse error '%U'", format_unformat_error, i);
11622           return -99;
11623         }
11624     }
11625
11626   if (sw_if_index_set == 0)
11627     {
11628       errmsg ("missing interface name or sw_if_index");
11629       return -99;
11630     }
11631
11632
11633   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11634
11635   mp->sw_if_index = ntohl (sw_if_index);
11636   mp->ip4_table_index = ntohl (ip4_table_index);
11637   mp->ip6_table_index = ntohl (ip6_table_index);
11638   mp->other_table_index = ntohl (other_table_index);
11639   mp->is_input = (u8) is_input;
11640
11641   S (mp);
11642   W (ret);
11643   return ret;
11644 }
11645
11646 static int
11647 api_set_ipfix_exporter (vat_main_t * vam)
11648 {
11649   unformat_input_t *i = vam->input;
11650   vl_api_set_ipfix_exporter_t *mp;
11651   ip4_address_t collector_address;
11652   u8 collector_address_set = 0;
11653   u32 collector_port = ~0;
11654   ip4_address_t src_address;
11655   u8 src_address_set = 0;
11656   u32 vrf_id = ~0;
11657   u32 path_mtu = ~0;
11658   u32 template_interval = ~0;
11659   u8 udp_checksum = 0;
11660   int ret;
11661
11662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11663     {
11664       if (unformat (i, "collector_address %U", unformat_ip4_address,
11665                     &collector_address))
11666         collector_address_set = 1;
11667       else if (unformat (i, "collector_port %d", &collector_port))
11668         ;
11669       else if (unformat (i, "src_address %U", unformat_ip4_address,
11670                          &src_address))
11671         src_address_set = 1;
11672       else if (unformat (i, "vrf_id %d", &vrf_id))
11673         ;
11674       else if (unformat (i, "path_mtu %d", &path_mtu))
11675         ;
11676       else if (unformat (i, "template_interval %d", &template_interval))
11677         ;
11678       else if (unformat (i, "udp_checksum"))
11679         udp_checksum = 1;
11680       else
11681         break;
11682     }
11683
11684   if (collector_address_set == 0)
11685     {
11686       errmsg ("collector_address required");
11687       return -99;
11688     }
11689
11690   if (src_address_set == 0)
11691     {
11692       errmsg ("src_address required");
11693       return -99;
11694     }
11695
11696   M (SET_IPFIX_EXPORTER, mp);
11697
11698   memcpy (mp->collector_address, collector_address.data,
11699           sizeof (collector_address.data));
11700   mp->collector_port = htons ((u16) collector_port);
11701   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11702   mp->vrf_id = htonl (vrf_id);
11703   mp->path_mtu = htonl (path_mtu);
11704   mp->template_interval = htonl (template_interval);
11705   mp->udp_checksum = udp_checksum;
11706
11707   S (mp);
11708   W (ret);
11709   return ret;
11710 }
11711
11712 static int
11713 api_set_ipfix_classify_stream (vat_main_t * vam)
11714 {
11715   unformat_input_t *i = vam->input;
11716   vl_api_set_ipfix_classify_stream_t *mp;
11717   u32 domain_id = 0;
11718   u32 src_port = UDP_DST_PORT_ipfix;
11719   int ret;
11720
11721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11722     {
11723       if (unformat (i, "domain %d", &domain_id))
11724         ;
11725       else if (unformat (i, "src_port %d", &src_port))
11726         ;
11727       else
11728         {
11729           errmsg ("unknown input `%U'", format_unformat_error, i);
11730           return -99;
11731         }
11732     }
11733
11734   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11735
11736   mp->domain_id = htonl (domain_id);
11737   mp->src_port = htons ((u16) src_port);
11738
11739   S (mp);
11740   W (ret);
11741   return ret;
11742 }
11743
11744 static int
11745 api_ipfix_classify_table_add_del (vat_main_t * vam)
11746 {
11747   unformat_input_t *i = vam->input;
11748   vl_api_ipfix_classify_table_add_del_t *mp;
11749   int is_add = -1;
11750   u32 classify_table_index = ~0;
11751   u8 ip_version = 0;
11752   u8 transport_protocol = 255;
11753   int ret;
11754
11755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11756     {
11757       if (unformat (i, "add"))
11758         is_add = 1;
11759       else if (unformat (i, "del"))
11760         is_add = 0;
11761       else if (unformat (i, "table %d", &classify_table_index))
11762         ;
11763       else if (unformat (i, "ip4"))
11764         ip_version = 4;
11765       else if (unformat (i, "ip6"))
11766         ip_version = 6;
11767       else if (unformat (i, "tcp"))
11768         transport_protocol = 6;
11769       else if (unformat (i, "udp"))
11770         transport_protocol = 17;
11771       else
11772         {
11773           errmsg ("unknown input `%U'", format_unformat_error, i);
11774           return -99;
11775         }
11776     }
11777
11778   if (is_add == -1)
11779     {
11780       errmsg ("expecting: add|del");
11781       return -99;
11782     }
11783   if (classify_table_index == ~0)
11784     {
11785       errmsg ("classifier table not specified");
11786       return -99;
11787     }
11788   if (ip_version == 0)
11789     {
11790       errmsg ("IP version not specified");
11791       return -99;
11792     }
11793
11794   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11795
11796   mp->is_add = is_add;
11797   mp->table_id = htonl (classify_table_index);
11798   mp->ip_version = ip_version;
11799   mp->transport_protocol = transport_protocol;
11800
11801   S (mp);
11802   W (ret);
11803   return ret;
11804 }
11805
11806 static int
11807 api_get_node_index (vat_main_t * vam)
11808 {
11809   unformat_input_t *i = vam->input;
11810   vl_api_get_node_index_t *mp;
11811   u8 *name = 0;
11812   int ret;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "node %s", &name))
11817         ;
11818       else
11819         break;
11820     }
11821   if (name == 0)
11822     {
11823       errmsg ("node name required");
11824       return -99;
11825     }
11826   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11827     {
11828       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11829       return -99;
11830     }
11831
11832   M (GET_NODE_INDEX, mp);
11833   clib_memcpy (mp->node_name, name, vec_len (name));
11834   vec_free (name);
11835
11836   S (mp);
11837   W (ret);
11838   return ret;
11839 }
11840
11841 static int
11842 api_get_next_index (vat_main_t * vam)
11843 {
11844   unformat_input_t *i = vam->input;
11845   vl_api_get_next_index_t *mp;
11846   u8 *node_name = 0, *next_node_name = 0;
11847   int ret;
11848
11849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11850     {
11851       if (unformat (i, "node-name %s", &node_name))
11852         ;
11853       else if (unformat (i, "next-node-name %s", &next_node_name))
11854         break;
11855     }
11856
11857   if (node_name == 0)
11858     {
11859       errmsg ("node name required");
11860       return -99;
11861     }
11862   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11863     {
11864       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11865       return -99;
11866     }
11867
11868   if (next_node_name == 0)
11869     {
11870       errmsg ("next node name required");
11871       return -99;
11872     }
11873   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11874     {
11875       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11876       return -99;
11877     }
11878
11879   M (GET_NEXT_INDEX, mp);
11880   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11881   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11882   vec_free (node_name);
11883   vec_free (next_node_name);
11884
11885   S (mp);
11886   W (ret);
11887   return ret;
11888 }
11889
11890 static int
11891 api_add_node_next (vat_main_t * vam)
11892 {
11893   unformat_input_t *i = vam->input;
11894   vl_api_add_node_next_t *mp;
11895   u8 *name = 0;
11896   u8 *next = 0;
11897   int ret;
11898
11899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11900     {
11901       if (unformat (i, "node %s", &name))
11902         ;
11903       else if (unformat (i, "next %s", &next))
11904         ;
11905       else
11906         break;
11907     }
11908   if (name == 0)
11909     {
11910       errmsg ("node name required");
11911       return -99;
11912     }
11913   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11914     {
11915       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11916       return -99;
11917     }
11918   if (next == 0)
11919     {
11920       errmsg ("next node required");
11921       return -99;
11922     }
11923   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11924     {
11925       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11926       return -99;
11927     }
11928
11929   M (ADD_NODE_NEXT, mp);
11930   clib_memcpy (mp->node_name, name, vec_len (name));
11931   clib_memcpy (mp->next_name, next, vec_len (next));
11932   vec_free (name);
11933   vec_free (next);
11934
11935   S (mp);
11936   W (ret);
11937   return ret;
11938 }
11939
11940 static int
11941 api_l2tpv3_create_tunnel (vat_main_t * vam)
11942 {
11943   unformat_input_t *i = vam->input;
11944   ip6_address_t client_address, our_address;
11945   int client_address_set = 0;
11946   int our_address_set = 0;
11947   u32 local_session_id = 0;
11948   u32 remote_session_id = 0;
11949   u64 local_cookie = 0;
11950   u64 remote_cookie = 0;
11951   u8 l2_sublayer_present = 0;
11952   vl_api_l2tpv3_create_tunnel_t *mp;
11953   int ret;
11954
11955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11956     {
11957       if (unformat (i, "client_address %U", unformat_ip6_address,
11958                     &client_address))
11959         client_address_set = 1;
11960       else if (unformat (i, "our_address %U", unformat_ip6_address,
11961                          &our_address))
11962         our_address_set = 1;
11963       else if (unformat (i, "local_session_id %d", &local_session_id))
11964         ;
11965       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11966         ;
11967       else if (unformat (i, "local_cookie %lld", &local_cookie))
11968         ;
11969       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11970         ;
11971       else if (unformat (i, "l2-sublayer-present"))
11972         l2_sublayer_present = 1;
11973       else
11974         break;
11975     }
11976
11977   if (client_address_set == 0)
11978     {
11979       errmsg ("client_address required");
11980       return -99;
11981     }
11982
11983   if (our_address_set == 0)
11984     {
11985       errmsg ("our_address required");
11986       return -99;
11987     }
11988
11989   M (L2TPV3_CREATE_TUNNEL, mp);
11990
11991   clib_memcpy (mp->client_address, client_address.as_u8,
11992                sizeof (mp->client_address));
11993
11994   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11995
11996   mp->local_session_id = ntohl (local_session_id);
11997   mp->remote_session_id = ntohl (remote_session_id);
11998   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11999   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12000   mp->l2_sublayer_present = l2_sublayer_present;
12001   mp->is_ipv6 = 1;
12002
12003   S (mp);
12004   W (ret);
12005   return ret;
12006 }
12007
12008 static int
12009 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12010 {
12011   unformat_input_t *i = vam->input;
12012   u32 sw_if_index;
12013   u8 sw_if_index_set = 0;
12014   u64 new_local_cookie = 0;
12015   u64 new_remote_cookie = 0;
12016   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12017   int ret;
12018
12019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12022         sw_if_index_set = 1;
12023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12024         sw_if_index_set = 1;
12025       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12026         ;
12027       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12028         ;
12029       else
12030         break;
12031     }
12032
12033   if (sw_if_index_set == 0)
12034     {
12035       errmsg ("missing interface name or sw_if_index");
12036       return -99;
12037     }
12038
12039   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12040
12041   mp->sw_if_index = ntohl (sw_if_index);
12042   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12043   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12044
12045   S (mp);
12046   W (ret);
12047   return ret;
12048 }
12049
12050 static int
12051 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12052 {
12053   unformat_input_t *i = vam->input;
12054   vl_api_l2tpv3_interface_enable_disable_t *mp;
12055   u32 sw_if_index;
12056   u8 sw_if_index_set = 0;
12057   u8 enable_disable = 1;
12058   int ret;
12059
12060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12061     {
12062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12063         sw_if_index_set = 1;
12064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12065         sw_if_index_set = 1;
12066       else if (unformat (i, "enable"))
12067         enable_disable = 1;
12068       else if (unformat (i, "disable"))
12069         enable_disable = 0;
12070       else
12071         break;
12072     }
12073
12074   if (sw_if_index_set == 0)
12075     {
12076       errmsg ("missing interface name or sw_if_index");
12077       return -99;
12078     }
12079
12080   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12081
12082   mp->sw_if_index = ntohl (sw_if_index);
12083   mp->enable_disable = enable_disable;
12084
12085   S (mp);
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static int
12091 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12092 {
12093   unformat_input_t *i = vam->input;
12094   vl_api_l2tpv3_set_lookup_key_t *mp;
12095   u8 key = ~0;
12096   int ret;
12097
12098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12099     {
12100       if (unformat (i, "lookup_v6_src"))
12101         key = L2T_LOOKUP_SRC_ADDRESS;
12102       else if (unformat (i, "lookup_v6_dst"))
12103         key = L2T_LOOKUP_DST_ADDRESS;
12104       else if (unformat (i, "lookup_session_id"))
12105         key = L2T_LOOKUP_SESSION_ID;
12106       else
12107         break;
12108     }
12109
12110   if (key == (u8) ~ 0)
12111     {
12112       errmsg ("l2tp session lookup key unset");
12113       return -99;
12114     }
12115
12116   M (L2TPV3_SET_LOOKUP_KEY, mp);
12117
12118   mp->key = key;
12119
12120   S (mp);
12121   W (ret);
12122   return ret;
12123 }
12124
12125 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12126   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12127 {
12128   vat_main_t *vam = &vat_main;
12129
12130   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12131          format_ip6_address, mp->our_address,
12132          format_ip6_address, mp->client_address,
12133          clib_net_to_host_u32 (mp->sw_if_index));
12134
12135   print (vam->ofp,
12136          "   local cookies %016llx %016llx remote cookie %016llx",
12137          clib_net_to_host_u64 (mp->local_cookie[0]),
12138          clib_net_to_host_u64 (mp->local_cookie[1]),
12139          clib_net_to_host_u64 (mp->remote_cookie));
12140
12141   print (vam->ofp, "   local session-id %d remote session-id %d",
12142          clib_net_to_host_u32 (mp->local_session_id),
12143          clib_net_to_host_u32 (mp->remote_session_id));
12144
12145   print (vam->ofp, "   l2 specific sublayer %s\n",
12146          mp->l2_sublayer_present ? "preset" : "absent");
12147
12148 }
12149
12150 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12151   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12152 {
12153   vat_main_t *vam = &vat_main;
12154   vat_json_node_t *node = NULL;
12155   struct in6_addr addr;
12156
12157   if (VAT_JSON_ARRAY != vam->json_tree.type)
12158     {
12159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12160       vat_json_init_array (&vam->json_tree);
12161     }
12162   node = vat_json_array_add (&vam->json_tree);
12163
12164   vat_json_init_object (node);
12165
12166   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12167   vat_json_object_add_ip6 (node, "our_address", addr);
12168   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12169   vat_json_object_add_ip6 (node, "client_address", addr);
12170
12171   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12172   vat_json_init_array (lc);
12173   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12174   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12175   vat_json_object_add_uint (node, "remote_cookie",
12176                             clib_net_to_host_u64 (mp->remote_cookie));
12177
12178   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12179   vat_json_object_add_uint (node, "local_session_id",
12180                             clib_net_to_host_u32 (mp->local_session_id));
12181   vat_json_object_add_uint (node, "remote_session_id",
12182                             clib_net_to_host_u32 (mp->remote_session_id));
12183   vat_json_object_add_string_copy (node, "l2_sublayer",
12184                                    mp->l2_sublayer_present ? (u8 *) "present"
12185                                    : (u8 *) "absent");
12186 }
12187
12188 static int
12189 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12190 {
12191   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12192   vl_api_control_ping_t *mp_ping;
12193   int ret;
12194
12195   /* Get list of l2tpv3-tunnel interfaces */
12196   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12197   S (mp);
12198
12199   /* Use a control ping for synchronization */
12200   MPING (CONTROL_PING, mp_ping);
12201   S (mp_ping);
12202
12203   W (ret);
12204   return ret;
12205 }
12206
12207
12208 static void vl_api_sw_interface_tap_v2_details_t_handler
12209   (vl_api_sw_interface_tap_v2_details_t * mp)
12210 {
12211   vat_main_t *vam = &vat_main;
12212
12213   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12214                     mp->host_ip4_prefix_len);
12215   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12216                     mp->host_ip6_prefix_len);
12217
12218   print (vam->ofp,
12219          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12220          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12221          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12222          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12223          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12224
12225   vec_free (ip4);
12226   vec_free (ip6);
12227 }
12228
12229 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12230   (vl_api_sw_interface_tap_v2_details_t * mp)
12231 {
12232   vat_main_t *vam = &vat_main;
12233   vat_json_node_t *node = NULL;
12234
12235   if (VAT_JSON_ARRAY != vam->json_tree.type)
12236     {
12237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12238       vat_json_init_array (&vam->json_tree);
12239     }
12240   node = vat_json_array_add (&vam->json_tree);
12241
12242   vat_json_init_object (node);
12243   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12245   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12246   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12247   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12248   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12249   vat_json_object_add_string_copy (node, "host_mac_addr",
12250                                    format (0, "%U", format_ethernet_address,
12251                                            &mp->host_mac_addr));
12252   vat_json_object_add_string_copy (node, "host_namespace",
12253                                    mp->host_namespace);
12254   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12255   vat_json_object_add_string_copy (node, "host_ip4_addr",
12256                                    format (0, "%U/%d", format_ip4_address,
12257                                            mp->host_ip4_addr,
12258                                            mp->host_ip4_prefix_len));
12259   vat_json_object_add_string_copy (node, "host_ip6_addr",
12260                                    format (0, "%U/%d", format_ip6_address,
12261                                            mp->host_ip6_addr,
12262                                            mp->host_ip6_prefix_len));
12263
12264 }
12265
12266 static int
12267 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12268 {
12269   vl_api_sw_interface_tap_v2_dump_t *mp;
12270   vl_api_control_ping_t *mp_ping;
12271   int ret;
12272
12273   print (vam->ofp,
12274          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12275          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12276          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12277          "host_ip6_addr");
12278
12279   /* Get list of tap interfaces */
12280   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   MPING (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static void vl_api_sw_interface_virtio_pci_details_t_handler
12292   (vl_api_sw_interface_virtio_pci_details_t * mp)
12293 {
12294   vat_main_t *vam = &vat_main;
12295
12296   typedef union
12297   {
12298     struct
12299     {
12300       u16 domain;
12301       u8 bus;
12302       u8 slot:5;
12303       u8 function:3;
12304     };
12305     u32 as_u32;
12306   } pci_addr_t;
12307   pci_addr_t addr;
12308   addr.as_u32 = ntohl (mp->pci_addr);
12309   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12310                          addr.slot, addr.function);
12311
12312   print (vam->ofp,
12313          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12314          pci_addr, ntohl (mp->sw_if_index),
12315          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12316          format_ethernet_address, mp->mac_addr,
12317          clib_net_to_host_u64 (mp->features));
12318   vec_free (pci_addr);
12319 }
12320
12321 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12322   (vl_api_sw_interface_virtio_pci_details_t * mp)
12323 {
12324   vat_main_t *vam = &vat_main;
12325   vat_json_node_t *node = NULL;
12326
12327   if (VAT_JSON_ARRAY != vam->json_tree.type)
12328     {
12329       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12330       vat_json_init_array (&vam->json_tree);
12331     }
12332   node = vat_json_array_add (&vam->json_tree);
12333
12334   vat_json_init_object (node);
12335   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12336   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12337   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12338   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12339   vat_json_object_add_uint (node, "features",
12340                             clib_net_to_host_u64 (mp->features));
12341   vat_json_object_add_string_copy (node, "mac_addr",
12342                                    format (0, "%U", format_ethernet_address,
12343                                            &mp->mac_addr));
12344 }
12345
12346 static int
12347 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12348 {
12349   vl_api_sw_interface_virtio_pci_dump_t *mp;
12350   vl_api_control_ping_t *mp_ping;
12351   int ret;
12352
12353   print (vam->ofp,
12354          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12355          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12356          "mac_addr", "features");
12357
12358   /* Get list of tap interfaces */
12359   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12360   S (mp);
12361
12362   /* Use a control ping for synchronization */
12363   MPING (CONTROL_PING, mp_ping);
12364   S (mp_ping);
12365
12366   W (ret);
12367   return ret;
12368 }
12369
12370 static int
12371 api_vxlan_offload_rx (vat_main_t * vam)
12372 {
12373   unformat_input_t *line_input = vam->input;
12374   vl_api_vxlan_offload_rx_t *mp;
12375   u32 hw_if_index = ~0, rx_if_index = ~0;
12376   u8 is_add = 1;
12377   int ret;
12378
12379   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (line_input, "del"))
12382         is_add = 0;
12383       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12384                          &hw_if_index))
12385         ;
12386       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12387         ;
12388       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12389                          &rx_if_index))
12390         ;
12391       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12392         ;
12393       else
12394         {
12395           errmsg ("parse error '%U'", format_unformat_error, line_input);
12396           return -99;
12397         }
12398     }
12399
12400   if (hw_if_index == ~0)
12401     {
12402       errmsg ("no hw interface");
12403       return -99;
12404     }
12405
12406   if (rx_if_index == ~0)
12407     {
12408       errmsg ("no rx tunnel");
12409       return -99;
12410     }
12411
12412   M (VXLAN_OFFLOAD_RX, mp);
12413
12414   mp->hw_if_index = ntohl (hw_if_index);
12415   mp->sw_if_index = ntohl (rx_if_index);
12416   mp->enable = is_add;
12417
12418   S (mp);
12419   W (ret);
12420   return ret;
12421 }
12422
12423 static uword unformat_vxlan_decap_next
12424   (unformat_input_t * input, va_list * args)
12425 {
12426   u32 *result = va_arg (*args, u32 *);
12427   u32 tmp;
12428
12429   if (unformat (input, "l2"))
12430     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12431   else if (unformat (input, "%d", &tmp))
12432     *result = tmp;
12433   else
12434     return 0;
12435   return 1;
12436 }
12437
12438 static int
12439 api_vxlan_add_del_tunnel (vat_main_t * vam)
12440 {
12441   unformat_input_t *line_input = vam->input;
12442   vl_api_vxlan_add_del_tunnel_t *mp;
12443   ip46_address_t src, dst;
12444   u8 is_add = 1;
12445   u8 ipv4_set = 0, ipv6_set = 0;
12446   u8 src_set = 0;
12447   u8 dst_set = 0;
12448   u8 grp_set = 0;
12449   u32 instance = ~0;
12450   u32 mcast_sw_if_index = ~0;
12451   u32 encap_vrf_id = 0;
12452   u32 decap_next_index = ~0;
12453   u32 vni = 0;
12454   int ret;
12455
12456   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12457   clib_memset (&src, 0, sizeof src);
12458   clib_memset (&dst, 0, sizeof dst);
12459
12460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12461     {
12462       if (unformat (line_input, "del"))
12463         is_add = 0;
12464       else if (unformat (line_input, "instance %d", &instance))
12465         ;
12466       else
12467         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12468         {
12469           ipv4_set = 1;
12470           src_set = 1;
12471         }
12472       else
12473         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12474         {
12475           ipv4_set = 1;
12476           dst_set = 1;
12477         }
12478       else
12479         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12480         {
12481           ipv6_set = 1;
12482           src_set = 1;
12483         }
12484       else
12485         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12486         {
12487           ipv6_set = 1;
12488           dst_set = 1;
12489         }
12490       else if (unformat (line_input, "group %U %U",
12491                          unformat_ip4_address, &dst.ip4,
12492                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12493         {
12494           grp_set = dst_set = 1;
12495           ipv4_set = 1;
12496         }
12497       else if (unformat (line_input, "group %U",
12498                          unformat_ip4_address, &dst.ip4))
12499         {
12500           grp_set = dst_set = 1;
12501           ipv4_set = 1;
12502         }
12503       else if (unformat (line_input, "group %U %U",
12504                          unformat_ip6_address, &dst.ip6,
12505                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12506         {
12507           grp_set = dst_set = 1;
12508           ipv6_set = 1;
12509         }
12510       else if (unformat (line_input, "group %U",
12511                          unformat_ip6_address, &dst.ip6))
12512         {
12513           grp_set = dst_set = 1;
12514           ipv6_set = 1;
12515         }
12516       else
12517         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12518         ;
12519       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12520         ;
12521       else if (unformat (line_input, "decap-next %U",
12522                          unformat_vxlan_decap_next, &decap_next_index))
12523         ;
12524       else if (unformat (line_input, "vni %d", &vni))
12525         ;
12526       else
12527         {
12528           errmsg ("parse error '%U'", format_unformat_error, line_input);
12529           return -99;
12530         }
12531     }
12532
12533   if (src_set == 0)
12534     {
12535       errmsg ("tunnel src address not specified");
12536       return -99;
12537     }
12538   if (dst_set == 0)
12539     {
12540       errmsg ("tunnel dst address not specified");
12541       return -99;
12542     }
12543
12544   if (grp_set && !ip46_address_is_multicast (&dst))
12545     {
12546       errmsg ("tunnel group address not multicast");
12547       return -99;
12548     }
12549   if (grp_set && mcast_sw_if_index == ~0)
12550     {
12551       errmsg ("tunnel nonexistent multicast device");
12552       return -99;
12553     }
12554   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12555     {
12556       errmsg ("tunnel dst address must be unicast");
12557       return -99;
12558     }
12559
12560
12561   if (ipv4_set && ipv6_set)
12562     {
12563       errmsg ("both IPv4 and IPv6 addresses specified");
12564       return -99;
12565     }
12566
12567   if ((vni == 0) || (vni >> 24))
12568     {
12569       errmsg ("vni not specified or out of range");
12570       return -99;
12571     }
12572
12573   M (VXLAN_ADD_DEL_TUNNEL, mp);
12574
12575   if (ipv6_set)
12576     {
12577       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12578       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12579     }
12580   else
12581     {
12582       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12583       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12584     }
12585
12586   mp->instance = htonl (instance);
12587   mp->encap_vrf_id = ntohl (encap_vrf_id);
12588   mp->decap_next_index = ntohl (decap_next_index);
12589   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12590   mp->vni = ntohl (vni);
12591   mp->is_add = is_add;
12592   mp->is_ipv6 = ipv6_set;
12593
12594   S (mp);
12595   W (ret);
12596   return ret;
12597 }
12598
12599 static void vl_api_vxlan_tunnel_details_t_handler
12600   (vl_api_vxlan_tunnel_details_t * mp)
12601 {
12602   vat_main_t *vam = &vat_main;
12603   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12604   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12605
12606   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12607          ntohl (mp->sw_if_index),
12608          ntohl (mp->instance),
12609          format_ip46_address, &src, IP46_TYPE_ANY,
12610          format_ip46_address, &dst, IP46_TYPE_ANY,
12611          ntohl (mp->encap_vrf_id),
12612          ntohl (mp->decap_next_index), ntohl (mp->vni),
12613          ntohl (mp->mcast_sw_if_index));
12614 }
12615
12616 static void vl_api_vxlan_tunnel_details_t_handler_json
12617   (vl_api_vxlan_tunnel_details_t * mp)
12618 {
12619   vat_main_t *vam = &vat_main;
12620   vat_json_node_t *node = NULL;
12621
12622   if (VAT_JSON_ARRAY != vam->json_tree.type)
12623     {
12624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12625       vat_json_init_array (&vam->json_tree);
12626     }
12627   node = vat_json_array_add (&vam->json_tree);
12628
12629   vat_json_init_object (node);
12630   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12631
12632   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12633
12634   if (mp->is_ipv6)
12635     {
12636       struct in6_addr ip6;
12637
12638       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12639       vat_json_object_add_ip6 (node, "src_address", ip6);
12640       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12641       vat_json_object_add_ip6 (node, "dst_address", ip6);
12642     }
12643   else
12644     {
12645       struct in_addr ip4;
12646
12647       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12648       vat_json_object_add_ip4 (node, "src_address", ip4);
12649       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12650       vat_json_object_add_ip4 (node, "dst_address", ip4);
12651     }
12652   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12653   vat_json_object_add_uint (node, "decap_next_index",
12654                             ntohl (mp->decap_next_index));
12655   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12656   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12657   vat_json_object_add_uint (node, "mcast_sw_if_index",
12658                             ntohl (mp->mcast_sw_if_index));
12659 }
12660
12661 static int
12662 api_vxlan_tunnel_dump (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_vxlan_tunnel_dump_t *mp;
12666   vl_api_control_ping_t *mp_ping;
12667   u32 sw_if_index;
12668   u8 sw_if_index_set = 0;
12669   int ret;
12670
12671   /* Parse args required to build the message */
12672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (i, "sw_if_index %d", &sw_if_index))
12675         sw_if_index_set = 1;
12676       else
12677         break;
12678     }
12679
12680   if (sw_if_index_set == 0)
12681     {
12682       sw_if_index = ~0;
12683     }
12684
12685   if (!vam->json_output)
12686     {
12687       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12688              "sw_if_index", "instance", "src_address", "dst_address",
12689              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12690     }
12691
12692   /* Get list of vxlan-tunnel interfaces */
12693   M (VXLAN_TUNNEL_DUMP, mp);
12694
12695   mp->sw_if_index = htonl (sw_if_index);
12696
12697   S (mp);
12698
12699   /* Use a control ping for synchronization */
12700   MPING (CONTROL_PING, mp_ping);
12701   S (mp_ping);
12702
12703   W (ret);
12704   return ret;
12705 }
12706
12707 static uword unformat_geneve_decap_next
12708   (unformat_input_t * input, va_list * args)
12709 {
12710   u32 *result = va_arg (*args, u32 *);
12711   u32 tmp;
12712
12713   if (unformat (input, "l2"))
12714     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12715   else if (unformat (input, "%d", &tmp))
12716     *result = tmp;
12717   else
12718     return 0;
12719   return 1;
12720 }
12721
12722 static int
12723 api_geneve_add_del_tunnel (vat_main_t * vam)
12724 {
12725   unformat_input_t *line_input = vam->input;
12726   vl_api_geneve_add_del_tunnel_t *mp;
12727   ip46_address_t src, dst;
12728   u8 is_add = 1;
12729   u8 ipv4_set = 0, ipv6_set = 0;
12730   u8 src_set = 0;
12731   u8 dst_set = 0;
12732   u8 grp_set = 0;
12733   u32 mcast_sw_if_index = ~0;
12734   u32 encap_vrf_id = 0;
12735   u32 decap_next_index = ~0;
12736   u32 vni = 0;
12737   int ret;
12738
12739   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12740   clib_memset (&src, 0, sizeof src);
12741   clib_memset (&dst, 0, sizeof dst);
12742
12743   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12744     {
12745       if (unformat (line_input, "del"))
12746         is_add = 0;
12747       else
12748         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12749         {
12750           ipv4_set = 1;
12751           src_set = 1;
12752         }
12753       else
12754         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12755         {
12756           ipv4_set = 1;
12757           dst_set = 1;
12758         }
12759       else
12760         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12761         {
12762           ipv6_set = 1;
12763           src_set = 1;
12764         }
12765       else
12766         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12767         {
12768           ipv6_set = 1;
12769           dst_set = 1;
12770         }
12771       else if (unformat (line_input, "group %U %U",
12772                          unformat_ip4_address, &dst.ip4,
12773                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12774         {
12775           grp_set = dst_set = 1;
12776           ipv4_set = 1;
12777         }
12778       else if (unformat (line_input, "group %U",
12779                          unformat_ip4_address, &dst.ip4))
12780         {
12781           grp_set = dst_set = 1;
12782           ipv4_set = 1;
12783         }
12784       else if (unformat (line_input, "group %U %U",
12785                          unformat_ip6_address, &dst.ip6,
12786                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12787         {
12788           grp_set = dst_set = 1;
12789           ipv6_set = 1;
12790         }
12791       else if (unformat (line_input, "group %U",
12792                          unformat_ip6_address, &dst.ip6))
12793         {
12794           grp_set = dst_set = 1;
12795           ipv6_set = 1;
12796         }
12797       else
12798         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12799         ;
12800       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12801         ;
12802       else if (unformat (line_input, "decap-next %U",
12803                          unformat_geneve_decap_next, &decap_next_index))
12804         ;
12805       else if (unformat (line_input, "vni %d", &vni))
12806         ;
12807       else
12808         {
12809           errmsg ("parse error '%U'", format_unformat_error, line_input);
12810           return -99;
12811         }
12812     }
12813
12814   if (src_set == 0)
12815     {
12816       errmsg ("tunnel src address not specified");
12817       return -99;
12818     }
12819   if (dst_set == 0)
12820     {
12821       errmsg ("tunnel dst address not specified");
12822       return -99;
12823     }
12824
12825   if (grp_set && !ip46_address_is_multicast (&dst))
12826     {
12827       errmsg ("tunnel group address not multicast");
12828       return -99;
12829     }
12830   if (grp_set && mcast_sw_if_index == ~0)
12831     {
12832       errmsg ("tunnel nonexistent multicast device");
12833       return -99;
12834     }
12835   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12836     {
12837       errmsg ("tunnel dst address must be unicast");
12838       return -99;
12839     }
12840
12841
12842   if (ipv4_set && ipv6_set)
12843     {
12844       errmsg ("both IPv4 and IPv6 addresses specified");
12845       return -99;
12846     }
12847
12848   if ((vni == 0) || (vni >> 24))
12849     {
12850       errmsg ("vni not specified or out of range");
12851       return -99;
12852     }
12853
12854   M (GENEVE_ADD_DEL_TUNNEL, mp);
12855
12856   if (ipv6_set)
12857     {
12858       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12859       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12860     }
12861   else
12862     {
12863       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12864       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12865     }
12866   mp->encap_vrf_id = ntohl (encap_vrf_id);
12867   mp->decap_next_index = ntohl (decap_next_index);
12868   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12869   mp->vni = ntohl (vni);
12870   mp->is_add = is_add;
12871   mp->is_ipv6 = ipv6_set;
12872
12873   S (mp);
12874   W (ret);
12875   return ret;
12876 }
12877
12878 static void vl_api_geneve_tunnel_details_t_handler
12879   (vl_api_geneve_tunnel_details_t * mp)
12880 {
12881   vat_main_t *vam = &vat_main;
12882   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12883   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12884
12885   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12886          ntohl (mp->sw_if_index),
12887          format_ip46_address, &src, IP46_TYPE_ANY,
12888          format_ip46_address, &dst, IP46_TYPE_ANY,
12889          ntohl (mp->encap_vrf_id),
12890          ntohl (mp->decap_next_index), ntohl (mp->vni),
12891          ntohl (mp->mcast_sw_if_index));
12892 }
12893
12894 static void vl_api_geneve_tunnel_details_t_handler_json
12895   (vl_api_geneve_tunnel_details_t * mp)
12896 {
12897   vat_main_t *vam = &vat_main;
12898   vat_json_node_t *node = NULL;
12899
12900   if (VAT_JSON_ARRAY != vam->json_tree.type)
12901     {
12902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12903       vat_json_init_array (&vam->json_tree);
12904     }
12905   node = vat_json_array_add (&vam->json_tree);
12906
12907   vat_json_init_object (node);
12908   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12909   if (mp->is_ipv6)
12910     {
12911       struct in6_addr ip6;
12912
12913       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12914       vat_json_object_add_ip6 (node, "src_address", ip6);
12915       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12916       vat_json_object_add_ip6 (node, "dst_address", ip6);
12917     }
12918   else
12919     {
12920       struct in_addr ip4;
12921
12922       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12923       vat_json_object_add_ip4 (node, "src_address", ip4);
12924       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12925       vat_json_object_add_ip4 (node, "dst_address", ip4);
12926     }
12927   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12928   vat_json_object_add_uint (node, "decap_next_index",
12929                             ntohl (mp->decap_next_index));
12930   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12931   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12932   vat_json_object_add_uint (node, "mcast_sw_if_index",
12933                             ntohl (mp->mcast_sw_if_index));
12934 }
12935
12936 static int
12937 api_geneve_tunnel_dump (vat_main_t * vam)
12938 {
12939   unformat_input_t *i = vam->input;
12940   vl_api_geneve_tunnel_dump_t *mp;
12941   vl_api_control_ping_t *mp_ping;
12942   u32 sw_if_index;
12943   u8 sw_if_index_set = 0;
12944   int ret;
12945
12946   /* Parse args required to build the message */
12947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12948     {
12949       if (unformat (i, "sw_if_index %d", &sw_if_index))
12950         sw_if_index_set = 1;
12951       else
12952         break;
12953     }
12954
12955   if (sw_if_index_set == 0)
12956     {
12957       sw_if_index = ~0;
12958     }
12959
12960   if (!vam->json_output)
12961     {
12962       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12963              "sw_if_index", "local_address", "remote_address",
12964              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12965     }
12966
12967   /* Get list of geneve-tunnel interfaces */
12968   M (GENEVE_TUNNEL_DUMP, mp);
12969
12970   mp->sw_if_index = htonl (sw_if_index);
12971
12972   S (mp);
12973
12974   /* Use a control ping for synchronization */
12975   M (CONTROL_PING, mp_ping);
12976   S (mp_ping);
12977
12978   W (ret);
12979   return ret;
12980 }
12981
12982 static int
12983 api_gre_tunnel_add_del (vat_main_t * vam)
12984 {
12985   unformat_input_t *line_input = vam->input;
12986   vl_api_address_t src = { }, dst =
12987   {
12988   };
12989   vl_api_gre_tunnel_add_del_t *mp;
12990   vl_api_gre_tunnel_type_t t_type;
12991   u8 is_add = 1;
12992   u8 src_set = 0;
12993   u8 dst_set = 0;
12994   u32 outer_fib_id = 0;
12995   u32 session_id = 0;
12996   u32 instance = ~0;
12997   int ret;
12998
12999   t_type = GRE_API_TUNNEL_TYPE_L3;
13000
13001   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13002     {
13003       if (unformat (line_input, "del"))
13004         is_add = 0;
13005       else if (unformat (line_input, "instance %d", &instance))
13006         ;
13007       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13008         {
13009           src_set = 1;
13010         }
13011       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13012         {
13013           dst_set = 1;
13014         }
13015       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13016         ;
13017       else if (unformat (line_input, "teb"))
13018         t_type = GRE_API_TUNNEL_TYPE_TEB;
13019       else if (unformat (line_input, "erspan %d", &session_id))
13020         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13021       else
13022         {
13023           errmsg ("parse error '%U'", format_unformat_error, line_input);
13024           return -99;
13025         }
13026     }
13027
13028   if (src_set == 0)
13029     {
13030       errmsg ("tunnel src address not specified");
13031       return -99;
13032     }
13033   if (dst_set == 0)
13034     {
13035       errmsg ("tunnel dst address not specified");
13036       return -99;
13037     }
13038
13039   M (GRE_TUNNEL_ADD_DEL, mp);
13040
13041   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13042   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13043
13044   mp->tunnel.instance = htonl (instance);
13045   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13046   mp->is_add = is_add;
13047   mp->tunnel.session_id = htons ((u16) session_id);
13048   mp->tunnel.type = htonl (t_type);
13049
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static void vl_api_gre_tunnel_details_t_handler
13056   (vl_api_gre_tunnel_details_t * mp)
13057 {
13058   vat_main_t *vam = &vat_main;
13059
13060   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13061          ntohl (mp->tunnel.sw_if_index),
13062          ntohl (mp->tunnel.instance),
13063          format_vl_api_address, &mp->tunnel.src,
13064          format_vl_api_address, &mp->tunnel.dst,
13065          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13066          ntohl (mp->tunnel.session_id));
13067 }
13068
13069 static void vl_api_gre_tunnel_details_t_handler_json
13070   (vl_api_gre_tunnel_details_t * mp)
13071 {
13072   vat_main_t *vam = &vat_main;
13073   vat_json_node_t *node = NULL;
13074
13075   if (VAT_JSON_ARRAY != vam->json_tree.type)
13076     {
13077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13078       vat_json_init_array (&vam->json_tree);
13079     }
13080   node = vat_json_array_add (&vam->json_tree);
13081
13082   vat_json_init_object (node);
13083   vat_json_object_add_uint (node, "sw_if_index",
13084                             ntohl (mp->tunnel.sw_if_index));
13085   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13086
13087   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13088   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13089   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13090   vat_json_object_add_uint (node, "outer_fib_id",
13091                             ntohl (mp->tunnel.outer_fib_id));
13092   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13093 }
13094
13095 static int
13096 api_gre_tunnel_dump (vat_main_t * vam)
13097 {
13098   unformat_input_t *i = vam->input;
13099   vl_api_gre_tunnel_dump_t *mp;
13100   vl_api_control_ping_t *mp_ping;
13101   u32 sw_if_index;
13102   u8 sw_if_index_set = 0;
13103   int ret;
13104
13105   /* Parse args required to build the message */
13106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13107     {
13108       if (unformat (i, "sw_if_index %d", &sw_if_index))
13109         sw_if_index_set = 1;
13110       else
13111         break;
13112     }
13113
13114   if (sw_if_index_set == 0)
13115     {
13116       sw_if_index = ~0;
13117     }
13118
13119   if (!vam->json_output)
13120     {
13121       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13122              "sw_if_index", "instance", "src_address", "dst_address",
13123              "tunnel_type", "outer_fib_id", "session_id");
13124     }
13125
13126   /* Get list of gre-tunnel interfaces */
13127   M (GRE_TUNNEL_DUMP, mp);
13128
13129   mp->sw_if_index = htonl (sw_if_index);
13130
13131   S (mp);
13132
13133   /* Use a control ping for synchronization */
13134   MPING (CONTROL_PING, mp_ping);
13135   S (mp_ping);
13136
13137   W (ret);
13138   return ret;
13139 }
13140
13141 static int
13142 api_l2_fib_clear_table (vat_main_t * vam)
13143 {
13144 //  unformat_input_t * i = vam->input;
13145   vl_api_l2_fib_clear_table_t *mp;
13146   int ret;
13147
13148   M (L2_FIB_CLEAR_TABLE, mp);
13149
13150   S (mp);
13151   W (ret);
13152   return ret;
13153 }
13154
13155 static int
13156 api_l2_interface_efp_filter (vat_main_t * vam)
13157 {
13158   unformat_input_t *i = vam->input;
13159   vl_api_l2_interface_efp_filter_t *mp;
13160   u32 sw_if_index;
13161   u8 enable = 1;
13162   u8 sw_if_index_set = 0;
13163   int ret;
13164
13165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13166     {
13167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13168         sw_if_index_set = 1;
13169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13170         sw_if_index_set = 1;
13171       else if (unformat (i, "enable"))
13172         enable = 1;
13173       else if (unformat (i, "disable"))
13174         enable = 0;
13175       else
13176         {
13177           clib_warning ("parse error '%U'", format_unformat_error, i);
13178           return -99;
13179         }
13180     }
13181
13182   if (sw_if_index_set == 0)
13183     {
13184       errmsg ("missing sw_if_index");
13185       return -99;
13186     }
13187
13188   M (L2_INTERFACE_EFP_FILTER, mp);
13189
13190   mp->sw_if_index = ntohl (sw_if_index);
13191   mp->enable_disable = enable;
13192
13193   S (mp);
13194   W (ret);
13195   return ret;
13196 }
13197
13198 #define foreach_vtr_op                          \
13199 _("disable",  L2_VTR_DISABLED)                  \
13200 _("push-1",  L2_VTR_PUSH_1)                     \
13201 _("push-2",  L2_VTR_PUSH_2)                     \
13202 _("pop-1",  L2_VTR_POP_1)                       \
13203 _("pop-2",  L2_VTR_POP_2)                       \
13204 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13205 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13206 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13207 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13208
13209 static int
13210 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13211 {
13212   unformat_input_t *i = vam->input;
13213   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13214   u32 sw_if_index;
13215   u8 sw_if_index_set = 0;
13216   u8 vtr_op_set = 0;
13217   u32 vtr_op = 0;
13218   u32 push_dot1q = 1;
13219   u32 tag1 = ~0;
13220   u32 tag2 = ~0;
13221   int ret;
13222
13223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13224     {
13225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13226         sw_if_index_set = 1;
13227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13228         sw_if_index_set = 1;
13229       else if (unformat (i, "vtr_op %d", &vtr_op))
13230         vtr_op_set = 1;
13231 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13232       foreach_vtr_op
13233 #undef _
13234         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13235         ;
13236       else if (unformat (i, "tag1 %d", &tag1))
13237         ;
13238       else if (unformat (i, "tag2 %d", &tag2))
13239         ;
13240       else
13241         {
13242           clib_warning ("parse error '%U'", format_unformat_error, i);
13243           return -99;
13244         }
13245     }
13246
13247   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13248     {
13249       errmsg ("missing vtr operation or sw_if_index");
13250       return -99;
13251     }
13252
13253   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13254   mp->sw_if_index = ntohl (sw_if_index);
13255   mp->vtr_op = ntohl (vtr_op);
13256   mp->push_dot1q = ntohl (push_dot1q);
13257   mp->tag1 = ntohl (tag1);
13258   mp->tag2 = ntohl (tag2);
13259
13260   S (mp);
13261   W (ret);
13262   return ret;
13263 }
13264
13265 static int
13266 api_create_vhost_user_if (vat_main_t * vam)
13267 {
13268   unformat_input_t *i = vam->input;
13269   vl_api_create_vhost_user_if_t *mp;
13270   u8 *file_name;
13271   u8 is_server = 0;
13272   u8 file_name_set = 0;
13273   u32 custom_dev_instance = ~0;
13274   u8 hwaddr[6];
13275   u8 use_custom_mac = 0;
13276   u8 disable_mrg_rxbuf = 0;
13277   u8 disable_indirect_desc = 0;
13278   u8 *tag = 0;
13279   int ret;
13280
13281   /* Shut up coverity */
13282   clib_memset (hwaddr, 0, sizeof (hwaddr));
13283
13284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (i, "socket %s", &file_name))
13287         {
13288           file_name_set = 1;
13289         }
13290       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13291         ;
13292       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13293         use_custom_mac = 1;
13294       else if (unformat (i, "server"))
13295         is_server = 1;
13296       else if (unformat (i, "disable_mrg_rxbuf"))
13297         disable_mrg_rxbuf = 1;
13298       else if (unformat (i, "disable_indirect_desc"))
13299         disable_indirect_desc = 1;
13300       else if (unformat (i, "tag %s", &tag))
13301         ;
13302       else
13303         break;
13304     }
13305
13306   if (file_name_set == 0)
13307     {
13308       errmsg ("missing socket file name");
13309       return -99;
13310     }
13311
13312   if (vec_len (file_name) > 255)
13313     {
13314       errmsg ("socket file name too long");
13315       return -99;
13316     }
13317   vec_add1 (file_name, 0);
13318
13319   M (CREATE_VHOST_USER_IF, mp);
13320
13321   mp->is_server = is_server;
13322   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13323   mp->disable_indirect_desc = disable_indirect_desc;
13324   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13325   vec_free (file_name);
13326   if (custom_dev_instance != ~0)
13327     {
13328       mp->renumber = 1;
13329       mp->custom_dev_instance = ntohl (custom_dev_instance);
13330     }
13331
13332   mp->use_custom_mac = use_custom_mac;
13333   clib_memcpy (mp->mac_address, hwaddr, 6);
13334   if (tag)
13335     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13336   vec_free (tag);
13337
13338   S (mp);
13339   W (ret);
13340   return ret;
13341 }
13342
13343 static int
13344 api_modify_vhost_user_if (vat_main_t * vam)
13345 {
13346   unformat_input_t *i = vam->input;
13347   vl_api_modify_vhost_user_if_t *mp;
13348   u8 *file_name;
13349   u8 is_server = 0;
13350   u8 file_name_set = 0;
13351   u32 custom_dev_instance = ~0;
13352   u8 sw_if_index_set = 0;
13353   u32 sw_if_index = (u32) ~ 0;
13354   int ret;
13355
13356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13357     {
13358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13359         sw_if_index_set = 1;
13360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13361         sw_if_index_set = 1;
13362       else if (unformat (i, "socket %s", &file_name))
13363         {
13364           file_name_set = 1;
13365         }
13366       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13367         ;
13368       else if (unformat (i, "server"))
13369         is_server = 1;
13370       else
13371         break;
13372     }
13373
13374   if (sw_if_index_set == 0)
13375     {
13376       errmsg ("missing sw_if_index or interface name");
13377       return -99;
13378     }
13379
13380   if (file_name_set == 0)
13381     {
13382       errmsg ("missing socket file name");
13383       return -99;
13384     }
13385
13386   if (vec_len (file_name) > 255)
13387     {
13388       errmsg ("socket file name too long");
13389       return -99;
13390     }
13391   vec_add1 (file_name, 0);
13392
13393   M (MODIFY_VHOST_USER_IF, mp);
13394
13395   mp->sw_if_index = ntohl (sw_if_index);
13396   mp->is_server = is_server;
13397   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13398   vec_free (file_name);
13399   if (custom_dev_instance != ~0)
13400     {
13401       mp->renumber = 1;
13402       mp->custom_dev_instance = ntohl (custom_dev_instance);
13403     }
13404
13405   S (mp);
13406   W (ret);
13407   return ret;
13408 }
13409
13410 static int
13411 api_delete_vhost_user_if (vat_main_t * vam)
13412 {
13413   unformat_input_t *i = vam->input;
13414   vl_api_delete_vhost_user_if_t *mp;
13415   u32 sw_if_index = ~0;
13416   u8 sw_if_index_set = 0;
13417   int ret;
13418
13419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13420     {
13421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13422         sw_if_index_set = 1;
13423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13424         sw_if_index_set = 1;
13425       else
13426         break;
13427     }
13428
13429   if (sw_if_index_set == 0)
13430     {
13431       errmsg ("missing sw_if_index or interface name");
13432       return -99;
13433     }
13434
13435
13436   M (DELETE_VHOST_USER_IF, mp);
13437
13438   mp->sw_if_index = ntohl (sw_if_index);
13439
13440   S (mp);
13441   W (ret);
13442   return ret;
13443 }
13444
13445 static void vl_api_sw_interface_vhost_user_details_t_handler
13446   (vl_api_sw_interface_vhost_user_details_t * mp)
13447 {
13448   vat_main_t *vam = &vat_main;
13449
13450   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13451          (char *) mp->interface_name,
13452          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13453          clib_net_to_host_u64 (mp->features), mp->is_server,
13454          ntohl (mp->num_regions), (char *) mp->sock_filename);
13455   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13456 }
13457
13458 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13459   (vl_api_sw_interface_vhost_user_details_t * mp)
13460 {
13461   vat_main_t *vam = &vat_main;
13462   vat_json_node_t *node = NULL;
13463
13464   if (VAT_JSON_ARRAY != vam->json_tree.type)
13465     {
13466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13467       vat_json_init_array (&vam->json_tree);
13468     }
13469   node = vat_json_array_add (&vam->json_tree);
13470
13471   vat_json_init_object (node);
13472   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13473   vat_json_object_add_string_copy (node, "interface_name",
13474                                    mp->interface_name);
13475   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13476                             ntohl (mp->virtio_net_hdr_sz));
13477   vat_json_object_add_uint (node, "features",
13478                             clib_net_to_host_u64 (mp->features));
13479   vat_json_object_add_uint (node, "is_server", mp->is_server);
13480   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13481   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13482   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13483 }
13484
13485 static int
13486 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13487 {
13488   vl_api_sw_interface_vhost_user_dump_t *mp;
13489   vl_api_control_ping_t *mp_ping;
13490   int ret;
13491   print (vam->ofp,
13492          "Interface name            idx hdr_sz features server regions filename");
13493
13494   /* Get list of vhost-user interfaces */
13495   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13496   S (mp);
13497
13498   /* Use a control ping for synchronization */
13499   MPING (CONTROL_PING, mp_ping);
13500   S (mp_ping);
13501
13502   W (ret);
13503   return ret;
13504 }
13505
13506 static int
13507 api_show_version (vat_main_t * vam)
13508 {
13509   vl_api_show_version_t *mp;
13510   int ret;
13511
13512   M (SHOW_VERSION, mp);
13513
13514   S (mp);
13515   W (ret);
13516   return ret;
13517 }
13518
13519
13520 static int
13521 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13522 {
13523   unformat_input_t *line_input = vam->input;
13524   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13525   ip4_address_t local4, remote4;
13526   ip6_address_t local6, remote6;
13527   u8 is_add = 1;
13528   u8 ipv4_set = 0, ipv6_set = 0;
13529   u8 local_set = 0;
13530   u8 remote_set = 0;
13531   u8 grp_set = 0;
13532   u32 mcast_sw_if_index = ~0;
13533   u32 encap_vrf_id = 0;
13534   u32 decap_vrf_id = 0;
13535   u8 protocol = ~0;
13536   u32 vni;
13537   u8 vni_set = 0;
13538   int ret;
13539
13540   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13541   clib_memset (&local4, 0, sizeof local4);
13542   clib_memset (&remote4, 0, sizeof remote4);
13543   clib_memset (&local6, 0, sizeof local6);
13544   clib_memset (&remote6, 0, sizeof remote6);
13545
13546   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13547     {
13548       if (unformat (line_input, "del"))
13549         is_add = 0;
13550       else if (unformat (line_input, "local %U",
13551                          unformat_ip4_address, &local4))
13552         {
13553           local_set = 1;
13554           ipv4_set = 1;
13555         }
13556       else if (unformat (line_input, "remote %U",
13557                          unformat_ip4_address, &remote4))
13558         {
13559           remote_set = 1;
13560           ipv4_set = 1;
13561         }
13562       else if (unformat (line_input, "local %U",
13563                          unformat_ip6_address, &local6))
13564         {
13565           local_set = 1;
13566           ipv6_set = 1;
13567         }
13568       else if (unformat (line_input, "remote %U",
13569                          unformat_ip6_address, &remote6))
13570         {
13571           remote_set = 1;
13572           ipv6_set = 1;
13573         }
13574       else if (unformat (line_input, "group %U %U",
13575                          unformat_ip4_address, &remote4,
13576                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13577         {
13578           grp_set = remote_set = 1;
13579           ipv4_set = 1;
13580         }
13581       else if (unformat (line_input, "group %U",
13582                          unformat_ip4_address, &remote4))
13583         {
13584           grp_set = remote_set = 1;
13585           ipv4_set = 1;
13586         }
13587       else if (unformat (line_input, "group %U %U",
13588                          unformat_ip6_address, &remote6,
13589                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13590         {
13591           grp_set = remote_set = 1;
13592           ipv6_set = 1;
13593         }
13594       else if (unformat (line_input, "group %U",
13595                          unformat_ip6_address, &remote6))
13596         {
13597           grp_set = remote_set = 1;
13598           ipv6_set = 1;
13599         }
13600       else
13601         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13602         ;
13603       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13604         ;
13605       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13606         ;
13607       else if (unformat (line_input, "vni %d", &vni))
13608         vni_set = 1;
13609       else if (unformat (line_input, "next-ip4"))
13610         protocol = 1;
13611       else if (unformat (line_input, "next-ip6"))
13612         protocol = 2;
13613       else if (unformat (line_input, "next-ethernet"))
13614         protocol = 3;
13615       else if (unformat (line_input, "next-nsh"))
13616         protocol = 4;
13617       else
13618         {
13619           errmsg ("parse error '%U'", format_unformat_error, line_input);
13620           return -99;
13621         }
13622     }
13623
13624   if (local_set == 0)
13625     {
13626       errmsg ("tunnel local address not specified");
13627       return -99;
13628     }
13629   if (remote_set == 0)
13630     {
13631       errmsg ("tunnel remote address not specified");
13632       return -99;
13633     }
13634   if (grp_set && mcast_sw_if_index == ~0)
13635     {
13636       errmsg ("tunnel nonexistent multicast device");
13637       return -99;
13638     }
13639   if (ipv4_set && ipv6_set)
13640     {
13641       errmsg ("both IPv4 and IPv6 addresses specified");
13642       return -99;
13643     }
13644
13645   if (vni_set == 0)
13646     {
13647       errmsg ("vni not specified");
13648       return -99;
13649     }
13650
13651   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13652
13653
13654   if (ipv6_set)
13655     {
13656       clib_memcpy (&mp->local, &local6, sizeof (local6));
13657       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13658     }
13659   else
13660     {
13661       clib_memcpy (&mp->local, &local4, sizeof (local4));
13662       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13663     }
13664
13665   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13666   mp->encap_vrf_id = ntohl (encap_vrf_id);
13667   mp->decap_vrf_id = ntohl (decap_vrf_id);
13668   mp->protocol = protocol;
13669   mp->vni = ntohl (vni);
13670   mp->is_add = is_add;
13671   mp->is_ipv6 = ipv6_set;
13672
13673   S (mp);
13674   W (ret);
13675   return ret;
13676 }
13677
13678 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13679   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13680 {
13681   vat_main_t *vam = &vat_main;
13682   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13683   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13684
13685   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13686          ntohl (mp->sw_if_index),
13687          format_ip46_address, &local, IP46_TYPE_ANY,
13688          format_ip46_address, &remote, IP46_TYPE_ANY,
13689          ntohl (mp->vni), mp->protocol,
13690          ntohl (mp->mcast_sw_if_index),
13691          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13692 }
13693
13694
13695 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13696   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13697 {
13698   vat_main_t *vam = &vat_main;
13699   vat_json_node_t *node = NULL;
13700   struct in_addr ip4;
13701   struct in6_addr ip6;
13702
13703   if (VAT_JSON_ARRAY != vam->json_tree.type)
13704     {
13705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13706       vat_json_init_array (&vam->json_tree);
13707     }
13708   node = vat_json_array_add (&vam->json_tree);
13709
13710   vat_json_init_object (node);
13711   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13712   if (mp->is_ipv6)
13713     {
13714       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13715       vat_json_object_add_ip6 (node, "local", ip6);
13716       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13717       vat_json_object_add_ip6 (node, "remote", ip6);
13718     }
13719   else
13720     {
13721       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13722       vat_json_object_add_ip4 (node, "local", ip4);
13723       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13724       vat_json_object_add_ip4 (node, "remote", ip4);
13725     }
13726   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13727   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13728   vat_json_object_add_uint (node, "mcast_sw_if_index",
13729                             ntohl (mp->mcast_sw_if_index));
13730   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13731   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13732   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13733 }
13734
13735 static int
13736 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13737 {
13738   unformat_input_t *i = vam->input;
13739   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13740   vl_api_control_ping_t *mp_ping;
13741   u32 sw_if_index;
13742   u8 sw_if_index_set = 0;
13743   int ret;
13744
13745   /* Parse args required to build the message */
13746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (i, "sw_if_index %d", &sw_if_index))
13749         sw_if_index_set = 1;
13750       else
13751         break;
13752     }
13753
13754   if (sw_if_index_set == 0)
13755     {
13756       sw_if_index = ~0;
13757     }
13758
13759   if (!vam->json_output)
13760     {
13761       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13762              "sw_if_index", "local", "remote", "vni",
13763              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13764     }
13765
13766   /* Get list of vxlan-tunnel interfaces */
13767   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13768
13769   mp->sw_if_index = htonl (sw_if_index);
13770
13771   S (mp);
13772
13773   /* Use a control ping for synchronization */
13774   MPING (CONTROL_PING, mp_ping);
13775   S (mp_ping);
13776
13777   W (ret);
13778   return ret;
13779 }
13780
13781 static void vl_api_l2_fib_table_details_t_handler
13782   (vl_api_l2_fib_table_details_t * mp)
13783 {
13784   vat_main_t *vam = &vat_main;
13785
13786   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13787          "       %d       %d     %d",
13788          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13789          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13790          mp->bvi_mac);
13791 }
13792
13793 static void vl_api_l2_fib_table_details_t_handler_json
13794   (vl_api_l2_fib_table_details_t * mp)
13795 {
13796   vat_main_t *vam = &vat_main;
13797   vat_json_node_t *node = NULL;
13798
13799   if (VAT_JSON_ARRAY != vam->json_tree.type)
13800     {
13801       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13802       vat_json_init_array (&vam->json_tree);
13803     }
13804   node = vat_json_array_add (&vam->json_tree);
13805
13806   vat_json_init_object (node);
13807   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13808   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13809   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13810   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13811   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13812   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13813 }
13814
13815 static int
13816 api_l2_fib_table_dump (vat_main_t * vam)
13817 {
13818   unformat_input_t *i = vam->input;
13819   vl_api_l2_fib_table_dump_t *mp;
13820   vl_api_control_ping_t *mp_ping;
13821   u32 bd_id;
13822   u8 bd_id_set = 0;
13823   int ret;
13824
13825   /* Parse args required to build the message */
13826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13827     {
13828       if (unformat (i, "bd_id %d", &bd_id))
13829         bd_id_set = 1;
13830       else
13831         break;
13832     }
13833
13834   if (bd_id_set == 0)
13835     {
13836       errmsg ("missing bridge domain");
13837       return -99;
13838     }
13839
13840   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13841
13842   /* Get list of l2 fib entries */
13843   M (L2_FIB_TABLE_DUMP, mp);
13844
13845   mp->bd_id = ntohl (bd_id);
13846   S (mp);
13847
13848   /* Use a control ping for synchronization */
13849   MPING (CONTROL_PING, mp_ping);
13850   S (mp_ping);
13851
13852   W (ret);
13853   return ret;
13854 }
13855
13856
13857 static int
13858 api_interface_name_renumber (vat_main_t * vam)
13859 {
13860   unformat_input_t *line_input = vam->input;
13861   vl_api_interface_name_renumber_t *mp;
13862   u32 sw_if_index = ~0;
13863   u32 new_show_dev_instance = ~0;
13864   int ret;
13865
13866   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13867     {
13868       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13869                     &sw_if_index))
13870         ;
13871       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13872         ;
13873       else if (unformat (line_input, "new_show_dev_instance %d",
13874                          &new_show_dev_instance))
13875         ;
13876       else
13877         break;
13878     }
13879
13880   if (sw_if_index == ~0)
13881     {
13882       errmsg ("missing interface name or sw_if_index");
13883       return -99;
13884     }
13885
13886   if (new_show_dev_instance == ~0)
13887     {
13888       errmsg ("missing new_show_dev_instance");
13889       return -99;
13890     }
13891
13892   M (INTERFACE_NAME_RENUMBER, mp);
13893
13894   mp->sw_if_index = ntohl (sw_if_index);
13895   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13896
13897   S (mp);
13898   W (ret);
13899   return ret;
13900 }
13901
13902 static int
13903 api_ip_probe_neighbor (vat_main_t * vam)
13904 {
13905   unformat_input_t *i = vam->input;
13906   vl_api_ip_probe_neighbor_t *mp;
13907   vl_api_address_t dst_adr = { };
13908   u8 int_set = 0;
13909   u8 adr_set = 0;
13910   u32 sw_if_index;
13911   int ret;
13912
13913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13916         int_set = 1;
13917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13918         int_set = 1;
13919       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13920         adr_set = 1;
13921       else
13922         break;
13923     }
13924
13925   if (int_set == 0)
13926     {
13927       errmsg ("missing interface");
13928       return -99;
13929     }
13930
13931   if (adr_set == 0)
13932     {
13933       errmsg ("missing addresses");
13934       return -99;
13935     }
13936
13937   M (IP_PROBE_NEIGHBOR, mp);
13938
13939   mp->sw_if_index = ntohl (sw_if_index);
13940   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13941
13942   S (mp);
13943   W (ret);
13944   return ret;
13945 }
13946
13947 static int
13948 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13949 {
13950   unformat_input_t *i = vam->input;
13951   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13952   u8 mode = IP_SCAN_V46_NEIGHBORS;
13953   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13954   int ret;
13955
13956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (i, "ip4"))
13959         mode = IP_SCAN_V4_NEIGHBORS;
13960       else if (unformat (i, "ip6"))
13961         mode = IP_SCAN_V6_NEIGHBORS;
13962       if (unformat (i, "both"))
13963         mode = IP_SCAN_V46_NEIGHBORS;
13964       else if (unformat (i, "disable"))
13965         mode = IP_SCAN_DISABLED;
13966       else if (unformat (i, "interval %d", &interval))
13967         ;
13968       else if (unformat (i, "max-time %d", &time))
13969         ;
13970       else if (unformat (i, "max-update %d", &update))
13971         ;
13972       else if (unformat (i, "delay %d", &delay))
13973         ;
13974       else if (unformat (i, "stale %d", &stale))
13975         ;
13976       else
13977         break;
13978     }
13979
13980   if (interval > 255)
13981     {
13982       errmsg ("interval cannot exceed 255 minutes.");
13983       return -99;
13984     }
13985   if (time > 255)
13986     {
13987       errmsg ("max-time cannot exceed 255 usec.");
13988       return -99;
13989     }
13990   if (update > 255)
13991     {
13992       errmsg ("max-update cannot exceed 255.");
13993       return -99;
13994     }
13995   if (delay > 255)
13996     {
13997       errmsg ("delay cannot exceed 255 msec.");
13998       return -99;
13999     }
14000   if (stale > 255)
14001     {
14002       errmsg ("stale cannot exceed 255 minutes.");
14003       return -99;
14004     }
14005
14006   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14007   mp->mode = mode;
14008   mp->scan_interval = interval;
14009   mp->max_proc_time = time;
14010   mp->max_update = update;
14011   mp->scan_int_delay = delay;
14012   mp->stale_threshold = stale;
14013
14014   S (mp);
14015   W (ret);
14016   return ret;
14017 }
14018
14019 static int
14020 api_want_ip4_arp_events (vat_main_t * vam)
14021 {
14022   unformat_input_t *line_input = vam->input;
14023   vl_api_want_ip4_arp_events_t *mp;
14024   ip4_address_t address;
14025   int address_set = 0;
14026   u32 enable_disable = 1;
14027   int ret;
14028
14029   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14030     {
14031       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14032         address_set = 1;
14033       else if (unformat (line_input, "del"))
14034         enable_disable = 0;
14035       else
14036         break;
14037     }
14038
14039   if (address_set == 0)
14040     {
14041       errmsg ("missing addresses");
14042       return -99;
14043     }
14044
14045   M (WANT_IP4_ARP_EVENTS, mp);
14046   mp->enable_disable = enable_disable;
14047   mp->pid = htonl (getpid ());
14048   clib_memcpy (mp->ip, &address, sizeof (address));
14049
14050   S (mp);
14051   W (ret);
14052   return ret;
14053 }
14054
14055 static int
14056 api_want_ip6_nd_events (vat_main_t * vam)
14057 {
14058   unformat_input_t *line_input = vam->input;
14059   vl_api_want_ip6_nd_events_t *mp;
14060   vl_api_ip6_address_t address;
14061   int address_set = 0;
14062   u32 enable_disable = 1;
14063   int ret;
14064
14065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat
14068           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14069         address_set = 1;
14070       else if (unformat (line_input, "del"))
14071         enable_disable = 0;
14072       else
14073         break;
14074     }
14075
14076   if (address_set == 0)
14077     {
14078       errmsg ("missing addresses");
14079       return -99;
14080     }
14081
14082   M (WANT_IP6_ND_EVENTS, mp);
14083   mp->enable_disable = enable_disable;
14084   mp->pid = htonl (getpid ());
14085   clib_memcpy (&mp->ip, &address, sizeof (address));
14086
14087   S (mp);
14088   W (ret);
14089   return ret;
14090 }
14091
14092 static int
14093 api_want_l2_macs_events (vat_main_t * vam)
14094 {
14095   unformat_input_t *line_input = vam->input;
14096   vl_api_want_l2_macs_events_t *mp;
14097   u8 enable_disable = 1;
14098   u32 scan_delay = 0;
14099   u32 max_macs_in_event = 0;
14100   u32 learn_limit = 0;
14101   int ret;
14102
14103   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14104     {
14105       if (unformat (line_input, "learn-limit %d", &learn_limit))
14106         ;
14107       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14108         ;
14109       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14110         ;
14111       else if (unformat (line_input, "disable"))
14112         enable_disable = 0;
14113       else
14114         break;
14115     }
14116
14117   M (WANT_L2_MACS_EVENTS, mp);
14118   mp->enable_disable = enable_disable;
14119   mp->pid = htonl (getpid ());
14120   mp->learn_limit = htonl (learn_limit);
14121   mp->scan_delay = (u8) scan_delay;
14122   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14123   S (mp);
14124   W (ret);
14125   return ret;
14126 }
14127
14128 static int
14129 api_input_acl_set_interface (vat_main_t * vam)
14130 {
14131   unformat_input_t *i = vam->input;
14132   vl_api_input_acl_set_interface_t *mp;
14133   u32 sw_if_index;
14134   int sw_if_index_set;
14135   u32 ip4_table_index = ~0;
14136   u32 ip6_table_index = ~0;
14137   u32 l2_table_index = ~0;
14138   u8 is_add = 1;
14139   int ret;
14140
14141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14142     {
14143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14144         sw_if_index_set = 1;
14145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14146         sw_if_index_set = 1;
14147       else if (unformat (i, "del"))
14148         is_add = 0;
14149       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14150         ;
14151       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14152         ;
14153       else if (unformat (i, "l2-table %d", &l2_table_index))
14154         ;
14155       else
14156         {
14157           clib_warning ("parse error '%U'", format_unformat_error, i);
14158           return -99;
14159         }
14160     }
14161
14162   if (sw_if_index_set == 0)
14163     {
14164       errmsg ("missing interface name or sw_if_index");
14165       return -99;
14166     }
14167
14168   M (INPUT_ACL_SET_INTERFACE, mp);
14169
14170   mp->sw_if_index = ntohl (sw_if_index);
14171   mp->ip4_table_index = ntohl (ip4_table_index);
14172   mp->ip6_table_index = ntohl (ip6_table_index);
14173   mp->l2_table_index = ntohl (l2_table_index);
14174   mp->is_add = is_add;
14175
14176   S (mp);
14177   W (ret);
14178   return ret;
14179 }
14180
14181 static int
14182 api_output_acl_set_interface (vat_main_t * vam)
14183 {
14184   unformat_input_t *i = vam->input;
14185   vl_api_output_acl_set_interface_t *mp;
14186   u32 sw_if_index;
14187   int sw_if_index_set;
14188   u32 ip4_table_index = ~0;
14189   u32 ip6_table_index = ~0;
14190   u32 l2_table_index = ~0;
14191   u8 is_add = 1;
14192   int ret;
14193
14194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14195     {
14196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14197         sw_if_index_set = 1;
14198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14199         sw_if_index_set = 1;
14200       else if (unformat (i, "del"))
14201         is_add = 0;
14202       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14203         ;
14204       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14205         ;
14206       else if (unformat (i, "l2-table %d", &l2_table_index))
14207         ;
14208       else
14209         {
14210           clib_warning ("parse error '%U'", format_unformat_error, i);
14211           return -99;
14212         }
14213     }
14214
14215   if (sw_if_index_set == 0)
14216     {
14217       errmsg ("missing interface name or sw_if_index");
14218       return -99;
14219     }
14220
14221   M (OUTPUT_ACL_SET_INTERFACE, mp);
14222
14223   mp->sw_if_index = ntohl (sw_if_index);
14224   mp->ip4_table_index = ntohl (ip4_table_index);
14225   mp->ip6_table_index = ntohl (ip6_table_index);
14226   mp->l2_table_index = ntohl (l2_table_index);
14227   mp->is_add = is_add;
14228
14229   S (mp);
14230   W (ret);
14231   return ret;
14232 }
14233
14234 static int
14235 api_ip_address_dump (vat_main_t * vam)
14236 {
14237   unformat_input_t *i = vam->input;
14238   vl_api_ip_address_dump_t *mp;
14239   vl_api_control_ping_t *mp_ping;
14240   u32 sw_if_index = ~0;
14241   u8 sw_if_index_set = 0;
14242   u8 ipv4_set = 0;
14243   u8 ipv6_set = 0;
14244   int ret;
14245
14246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (i, "sw_if_index %d", &sw_if_index))
14249         sw_if_index_set = 1;
14250       else
14251         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14252         sw_if_index_set = 1;
14253       else if (unformat (i, "ipv4"))
14254         ipv4_set = 1;
14255       else if (unformat (i, "ipv6"))
14256         ipv6_set = 1;
14257       else
14258         break;
14259     }
14260
14261   if (ipv4_set && ipv6_set)
14262     {
14263       errmsg ("ipv4 and ipv6 flags cannot be both set");
14264       return -99;
14265     }
14266
14267   if ((!ipv4_set) && (!ipv6_set))
14268     {
14269       errmsg ("no ipv4 nor ipv6 flag set");
14270       return -99;
14271     }
14272
14273   if (sw_if_index_set == 0)
14274     {
14275       errmsg ("missing interface name or sw_if_index");
14276       return -99;
14277     }
14278
14279   vam->current_sw_if_index = sw_if_index;
14280   vam->is_ipv6 = ipv6_set;
14281
14282   M (IP_ADDRESS_DUMP, mp);
14283   mp->sw_if_index = ntohl (sw_if_index);
14284   mp->is_ipv6 = ipv6_set;
14285   S (mp);
14286
14287   /* Use a control ping for synchronization */
14288   MPING (CONTROL_PING, mp_ping);
14289   S (mp_ping);
14290
14291   W (ret);
14292   return ret;
14293 }
14294
14295 static int
14296 api_ip_dump (vat_main_t * vam)
14297 {
14298   vl_api_ip_dump_t *mp;
14299   vl_api_control_ping_t *mp_ping;
14300   unformat_input_t *in = vam->input;
14301   int ipv4_set = 0;
14302   int ipv6_set = 0;
14303   int is_ipv6;
14304   int i;
14305   int ret;
14306
14307   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14308     {
14309       if (unformat (in, "ipv4"))
14310         ipv4_set = 1;
14311       else if (unformat (in, "ipv6"))
14312         ipv6_set = 1;
14313       else
14314         break;
14315     }
14316
14317   if (ipv4_set && ipv6_set)
14318     {
14319       errmsg ("ipv4 and ipv6 flags cannot be both set");
14320       return -99;
14321     }
14322
14323   if ((!ipv4_set) && (!ipv6_set))
14324     {
14325       errmsg ("no ipv4 nor ipv6 flag set");
14326       return -99;
14327     }
14328
14329   is_ipv6 = ipv6_set;
14330   vam->is_ipv6 = is_ipv6;
14331
14332   /* free old data */
14333   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14334     {
14335       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14336     }
14337   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14338
14339   M (IP_DUMP, mp);
14340   mp->is_ipv6 = ipv6_set;
14341   S (mp);
14342
14343   /* Use a control ping for synchronization */
14344   MPING (CONTROL_PING, mp_ping);
14345   S (mp_ping);
14346
14347   W (ret);
14348   return ret;
14349 }
14350
14351 static int
14352 api_ipsec_spd_add_del (vat_main_t * vam)
14353 {
14354   unformat_input_t *i = vam->input;
14355   vl_api_ipsec_spd_add_del_t *mp;
14356   u32 spd_id = ~0;
14357   u8 is_add = 1;
14358   int ret;
14359
14360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14361     {
14362       if (unformat (i, "spd_id %d", &spd_id))
14363         ;
14364       else if (unformat (i, "del"))
14365         is_add = 0;
14366       else
14367         {
14368           clib_warning ("parse error '%U'", format_unformat_error, i);
14369           return -99;
14370         }
14371     }
14372   if (spd_id == ~0)
14373     {
14374       errmsg ("spd_id must be set");
14375       return -99;
14376     }
14377
14378   M (IPSEC_SPD_ADD_DEL, mp);
14379
14380   mp->spd_id = ntohl (spd_id);
14381   mp->is_add = is_add;
14382
14383   S (mp);
14384   W (ret);
14385   return ret;
14386 }
14387
14388 static int
14389 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14390 {
14391   unformat_input_t *i = vam->input;
14392   vl_api_ipsec_interface_add_del_spd_t *mp;
14393   u32 sw_if_index;
14394   u8 sw_if_index_set = 0;
14395   u32 spd_id = (u32) ~ 0;
14396   u8 is_add = 1;
14397   int ret;
14398
14399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat (i, "del"))
14402         is_add = 0;
14403       else if (unformat (i, "spd_id %d", &spd_id))
14404         ;
14405       else
14406         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14407         sw_if_index_set = 1;
14408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14409         sw_if_index_set = 1;
14410       else
14411         {
14412           clib_warning ("parse error '%U'", format_unformat_error, i);
14413           return -99;
14414         }
14415
14416     }
14417
14418   if (spd_id == (u32) ~ 0)
14419     {
14420       errmsg ("spd_id must be set");
14421       return -99;
14422     }
14423
14424   if (sw_if_index_set == 0)
14425     {
14426       errmsg ("missing interface name or sw_if_index");
14427       return -99;
14428     }
14429
14430   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14431
14432   mp->spd_id = ntohl (spd_id);
14433   mp->sw_if_index = ntohl (sw_if_index);
14434   mp->is_add = is_add;
14435
14436   S (mp);
14437   W (ret);
14438   return ret;
14439 }
14440
14441 static int
14442 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14443 {
14444   unformat_input_t *i = vam->input;
14445   vl_api_ipsec_spd_entry_add_del_t *mp;
14446   u8 is_add = 1, is_outbound = 0;
14447   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14448   i32 priority = 0;
14449   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14450   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14451   vl_api_address_t laddr_start = { }, laddr_stop =
14452   {
14453   }, raddr_start =
14454   {
14455   }, raddr_stop =
14456   {
14457   };
14458   int ret;
14459
14460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14461     {
14462       if (unformat (i, "del"))
14463         is_add = 0;
14464       if (unformat (i, "outbound"))
14465         is_outbound = 1;
14466       if (unformat (i, "inbound"))
14467         is_outbound = 0;
14468       else if (unformat (i, "spd_id %d", &spd_id))
14469         ;
14470       else if (unformat (i, "sa_id %d", &sa_id))
14471         ;
14472       else if (unformat (i, "priority %d", &priority))
14473         ;
14474       else if (unformat (i, "protocol %d", &protocol))
14475         ;
14476       else if (unformat (i, "lport_start %d", &lport_start))
14477         ;
14478       else if (unformat (i, "lport_stop %d", &lport_stop))
14479         ;
14480       else if (unformat (i, "rport_start %d", &rport_start))
14481         ;
14482       else if (unformat (i, "rport_stop %d", &rport_stop))
14483         ;
14484       else if (unformat (i, "laddr_start %U",
14485                          unformat_vl_api_address, &laddr_start))
14486         ;
14487       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14488                          &laddr_stop))
14489         ;
14490       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14491                          &raddr_start))
14492         ;
14493       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14494                          &raddr_stop))
14495         ;
14496       else
14497         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14498         {
14499           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14500             {
14501               clib_warning ("unsupported action: 'resolve'");
14502               return -99;
14503             }
14504         }
14505       else
14506         {
14507           clib_warning ("parse error '%U'", format_unformat_error, i);
14508           return -99;
14509         }
14510
14511     }
14512
14513   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14514
14515   mp->is_add = is_add;
14516
14517   mp->entry.spd_id = ntohl (spd_id);
14518   mp->entry.priority = ntohl (priority);
14519   mp->entry.is_outbound = is_outbound;
14520
14521   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14522                sizeof (vl_api_address_t));
14523   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14524                sizeof (vl_api_address_t));
14525   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14526                sizeof (vl_api_address_t));
14527   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14528                sizeof (vl_api_address_t));
14529
14530   mp->entry.protocol = (u8) protocol;
14531   mp->entry.local_port_start = ntohs ((u16) lport_start);
14532   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14533   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14534   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14535   mp->entry.policy = (u8) policy;
14536   mp->entry.sa_id = ntohl (sa_id);
14537
14538   S (mp);
14539   W (ret);
14540   return ret;
14541 }
14542
14543 static int
14544 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14545 {
14546   unformat_input_t *i = vam->input;
14547   vl_api_ipsec_sad_entry_add_del_t *mp;
14548   u32 sad_id = 0, spi = 0;
14549   u8 *ck = 0, *ik = 0;
14550   u8 is_add = 1;
14551
14552   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14553   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14554   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14555   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14556   vl_api_address_t tun_src, tun_dst;
14557   int ret;
14558
14559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14560     {
14561       if (unformat (i, "del"))
14562         is_add = 0;
14563       else if (unformat (i, "sad_id %d", &sad_id))
14564         ;
14565       else if (unformat (i, "spi %d", &spi))
14566         ;
14567       else if (unformat (i, "esp"))
14568         protocol = IPSEC_API_PROTO_ESP;
14569       else
14570         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14571         {
14572           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14573           if (ADDRESS_IP6 == tun_src.af)
14574             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14575         }
14576       else
14577         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14578         {
14579           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14580           if (ADDRESS_IP6 == tun_src.af)
14581             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14582         }
14583       else
14584         if (unformat (i, "crypto_alg %U",
14585                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14586         ;
14587       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14588         ;
14589       else if (unformat (i, "integ_alg %U",
14590                          unformat_ipsec_api_integ_alg, &integ_alg))
14591         ;
14592       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14593         ;
14594       else
14595         {
14596           clib_warning ("parse error '%U'", format_unformat_error, i);
14597           return -99;
14598         }
14599
14600     }
14601
14602   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14603
14604   mp->is_add = is_add;
14605   mp->entry.sad_id = ntohl (sad_id);
14606   mp->entry.protocol = protocol;
14607   mp->entry.spi = ntohl (spi);
14608   mp->entry.flags = flags;
14609
14610   mp->entry.crypto_algorithm = crypto_alg;
14611   mp->entry.integrity_algorithm = integ_alg;
14612   mp->entry.crypto_key.length = vec_len (ck);
14613   mp->entry.integrity_key.length = vec_len (ik);
14614
14615   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14616     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14617
14618   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14619     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14620
14621   if (ck)
14622     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14623   if (ik)
14624     clib_memcpy (mp->entry.integrity_key.data, ik,
14625                  mp->entry.integrity_key.length);
14626
14627   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14628     {
14629       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14630                    sizeof (mp->entry.tunnel_src));
14631       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14632                    sizeof (mp->entry.tunnel_dst));
14633     }
14634
14635   S (mp);
14636   W (ret);
14637   return ret;
14638 }
14639
14640 static int
14641 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14642 {
14643   unformat_input_t *i = vam->input;
14644   vl_api_ipsec_tunnel_if_add_del_t *mp;
14645   u32 local_spi = 0, remote_spi = 0;
14646   u32 crypto_alg = 0, integ_alg = 0;
14647   u8 *lck = NULL, *rck = NULL;
14648   u8 *lik = NULL, *rik = NULL;
14649   vl_api_address_t local_ip = { 0 };
14650   vl_api_address_t remote_ip = { 0 };
14651   f64 before = 0;
14652   u8 is_add = 1;
14653   u8 esn = 0;
14654   u8 anti_replay = 0;
14655   u8 renumber = 0;
14656   u32 instance = ~0;
14657   u32 count = 1, jj;
14658   int ret = -1;
14659
14660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14661     {
14662       if (unformat (i, "del"))
14663         is_add = 0;
14664       else if (unformat (i, "esn"))
14665         esn = 1;
14666       else if (unformat (i, "anti-replay"))
14667         anti_replay = 1;
14668       else if (unformat (i, "count %d", &count))
14669         ;
14670       else if (unformat (i, "local_spi %d", &local_spi))
14671         ;
14672       else if (unformat (i, "remote_spi %d", &remote_spi))
14673         ;
14674       else
14675         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14676         ;
14677       else
14678         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14679         ;
14680       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14681         ;
14682       else
14683         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14684         ;
14685       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14686         ;
14687       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14688         ;
14689       else
14690         if (unformat
14691             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14692         {
14693           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14694             {
14695               errmsg ("unsupported crypto-alg: '%U'\n",
14696                       format_ipsec_crypto_alg, crypto_alg);
14697               return -99;
14698             }
14699         }
14700       else
14701         if (unformat
14702             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14703         {
14704           if (integ_alg >= IPSEC_INTEG_N_ALG)
14705             {
14706               errmsg ("unsupported integ-alg: '%U'\n",
14707                       format_ipsec_integ_alg, integ_alg);
14708               return -99;
14709             }
14710         }
14711       else if (unformat (i, "instance %u", &instance))
14712         renumber = 1;
14713       else
14714         {
14715           errmsg ("parse error '%U'\n", format_unformat_error, i);
14716           return -99;
14717         }
14718     }
14719
14720   if (count > 1)
14721     {
14722       /* Turn on async mode */
14723       vam->async_mode = 1;
14724       vam->async_errors = 0;
14725       before = vat_time_now (vam);
14726     }
14727
14728   for (jj = 0; jj < count; jj++)
14729     {
14730       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14731
14732       mp->is_add = is_add;
14733       mp->esn = esn;
14734       mp->anti_replay = anti_replay;
14735
14736       if (jj > 0)
14737         increment_address (&remote_ip);
14738
14739       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14740       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14741
14742       mp->local_spi = htonl (local_spi + jj);
14743       mp->remote_spi = htonl (remote_spi + jj);
14744       mp->crypto_alg = (u8) crypto_alg;
14745
14746       mp->local_crypto_key_len = 0;
14747       if (lck)
14748         {
14749           mp->local_crypto_key_len = vec_len (lck);
14750           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14751             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14752           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14753         }
14754
14755       mp->remote_crypto_key_len = 0;
14756       if (rck)
14757         {
14758           mp->remote_crypto_key_len = vec_len (rck);
14759           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14760             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14761           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14762         }
14763
14764       mp->integ_alg = (u8) integ_alg;
14765
14766       mp->local_integ_key_len = 0;
14767       if (lik)
14768         {
14769           mp->local_integ_key_len = vec_len (lik);
14770           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14771             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14772           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14773         }
14774
14775       mp->remote_integ_key_len = 0;
14776       if (rik)
14777         {
14778           mp->remote_integ_key_len = vec_len (rik);
14779           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14780             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14781           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14782         }
14783
14784       if (renumber)
14785         {
14786           mp->renumber = renumber;
14787           mp->show_instance = ntohl (instance);
14788         }
14789       S (mp);
14790     }
14791
14792   /* When testing multiple add/del ops, use a control-ping to sync */
14793   if (count > 1)
14794     {
14795       vl_api_control_ping_t *mp_ping;
14796       f64 after;
14797       f64 timeout;
14798
14799       /* Shut off async mode */
14800       vam->async_mode = 0;
14801
14802       MPING (CONTROL_PING, mp_ping);
14803       S (mp_ping);
14804
14805       timeout = vat_time_now (vam) + 1.0;
14806       while (vat_time_now (vam) < timeout)
14807         if (vam->result_ready == 1)
14808           goto out;
14809       vam->retval = -99;
14810
14811     out:
14812       if (vam->retval == -99)
14813         errmsg ("timeout");
14814
14815       if (vam->async_errors > 0)
14816         {
14817           errmsg ("%d asynchronous errors", vam->async_errors);
14818           vam->retval = -98;
14819         }
14820       vam->async_errors = 0;
14821       after = vat_time_now (vam);
14822
14823       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14824       if (jj > 0)
14825         count = jj;
14826
14827       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14828              count, after - before, count / (after - before));
14829     }
14830   else
14831     {
14832       /* Wait for a reply... */
14833       W (ret);
14834       return ret;
14835     }
14836
14837   return ret;
14838 }
14839
14840 static void
14841 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14842 {
14843   vat_main_t *vam = &vat_main;
14844
14845   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14846          "crypto_key %U integ_alg %u integ_key %U flags %x "
14847          "tunnel_src_addr %U tunnel_dst_addr %U "
14848          "salt %u seq_outbound %lu last_seq_inbound %lu "
14849          "replay_window %lu\n",
14850          ntohl (mp->entry.sad_id),
14851          ntohl (mp->sw_if_index),
14852          ntohl (mp->entry.spi),
14853          ntohl (mp->entry.protocol),
14854          ntohl (mp->entry.crypto_algorithm),
14855          format_hex_bytes, mp->entry.crypto_key.data,
14856          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14857          format_hex_bytes, mp->entry.integrity_key.data,
14858          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14859          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14860          &mp->entry.tunnel_dst, ntohl (mp->salt),
14861          clib_net_to_host_u64 (mp->seq_outbound),
14862          clib_net_to_host_u64 (mp->last_seq_inbound),
14863          clib_net_to_host_u64 (mp->replay_window));
14864 }
14865
14866 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14867 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14868
14869 static void vl_api_ipsec_sa_details_t_handler_json
14870   (vl_api_ipsec_sa_details_t * mp)
14871 {
14872   vat_main_t *vam = &vat_main;
14873   vat_json_node_t *node = NULL;
14874   vl_api_ipsec_sad_flags_t flags;
14875
14876   if (VAT_JSON_ARRAY != vam->json_tree.type)
14877     {
14878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14879       vat_json_init_array (&vam->json_tree);
14880     }
14881   node = vat_json_array_add (&vam->json_tree);
14882
14883   vat_json_init_object (node);
14884   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14885   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14886   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14887   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14888   vat_json_object_add_uint (node, "crypto_alg",
14889                             ntohl (mp->entry.crypto_algorithm));
14890   vat_json_object_add_uint (node, "integ_alg",
14891                             ntohl (mp->entry.integrity_algorithm));
14892   flags = ntohl (mp->entry.flags);
14893   vat_json_object_add_uint (node, "use_esn",
14894                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14895   vat_json_object_add_uint (node, "use_anti_replay",
14896                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14897   vat_json_object_add_uint (node, "is_tunnel",
14898                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14899   vat_json_object_add_uint (node, "is_tunnel_ip6",
14900                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14901   vat_json_object_add_uint (node, "udp_encap",
14902                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14903   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14904                              mp->entry.crypto_key.length);
14905   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14906                              mp->entry.integrity_key.length);
14907   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14908   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14909   vat_json_object_add_uint (node, "replay_window",
14910                             clib_net_to_host_u64 (mp->replay_window));
14911 }
14912
14913 static int
14914 api_ipsec_sa_dump (vat_main_t * vam)
14915 {
14916   unformat_input_t *i = vam->input;
14917   vl_api_ipsec_sa_dump_t *mp;
14918   vl_api_control_ping_t *mp_ping;
14919   u32 sa_id = ~0;
14920   int ret;
14921
14922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (i, "sa_id %d", &sa_id))
14925         ;
14926       else
14927         {
14928           clib_warning ("parse error '%U'", format_unformat_error, i);
14929           return -99;
14930         }
14931     }
14932
14933   M (IPSEC_SA_DUMP, mp);
14934
14935   mp->sa_id = ntohl (sa_id);
14936
14937   S (mp);
14938
14939   /* Use a control ping for synchronization */
14940   M (CONTROL_PING, mp_ping);
14941   S (mp_ping);
14942
14943   W (ret);
14944   return ret;
14945 }
14946
14947 static int
14948 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14949 {
14950   unformat_input_t *i = vam->input;
14951   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14952   u32 sw_if_index = ~0;
14953   u32 sa_id = ~0;
14954   u8 is_outbound = (u8) ~ 0;
14955   int ret;
14956
14957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14958     {
14959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14960         ;
14961       else if (unformat (i, "sa_id %d", &sa_id))
14962         ;
14963       else if (unformat (i, "outbound"))
14964         is_outbound = 1;
14965       else if (unformat (i, "inbound"))
14966         is_outbound = 0;
14967       else
14968         {
14969           clib_warning ("parse error '%U'", format_unformat_error, i);
14970           return -99;
14971         }
14972     }
14973
14974   if (sw_if_index == ~0)
14975     {
14976       errmsg ("interface must be specified");
14977       return -99;
14978     }
14979
14980   if (sa_id == ~0)
14981     {
14982       errmsg ("SA ID must be specified");
14983       return -99;
14984     }
14985
14986   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14987
14988   mp->sw_if_index = htonl (sw_if_index);
14989   mp->sa_id = htonl (sa_id);
14990   mp->is_outbound = is_outbound;
14991
14992   S (mp);
14993   W (ret);
14994
14995   return ret;
14996 }
14997
14998 static int
14999 api_get_first_msg_id (vat_main_t * vam)
15000 {
15001   vl_api_get_first_msg_id_t *mp;
15002   unformat_input_t *i = vam->input;
15003   u8 *name;
15004   u8 name_set = 0;
15005   int ret;
15006
15007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15008     {
15009       if (unformat (i, "client %s", &name))
15010         name_set = 1;
15011       else
15012         break;
15013     }
15014
15015   if (name_set == 0)
15016     {
15017       errmsg ("missing client name");
15018       return -99;
15019     }
15020   vec_add1 (name, 0);
15021
15022   if (vec_len (name) > 63)
15023     {
15024       errmsg ("client name too long");
15025       return -99;
15026     }
15027
15028   M (GET_FIRST_MSG_ID, mp);
15029   clib_memcpy (mp->name, name, vec_len (name));
15030   S (mp);
15031   W (ret);
15032   return ret;
15033 }
15034
15035 static int
15036 api_cop_interface_enable_disable (vat_main_t * vam)
15037 {
15038   unformat_input_t *line_input = vam->input;
15039   vl_api_cop_interface_enable_disable_t *mp;
15040   u32 sw_if_index = ~0;
15041   u8 enable_disable = 1;
15042   int ret;
15043
15044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15045     {
15046       if (unformat (line_input, "disable"))
15047         enable_disable = 0;
15048       if (unformat (line_input, "enable"))
15049         enable_disable = 1;
15050       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15051                          vam, &sw_if_index))
15052         ;
15053       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15054         ;
15055       else
15056         break;
15057     }
15058
15059   if (sw_if_index == ~0)
15060     {
15061       errmsg ("missing interface name or sw_if_index");
15062       return -99;
15063     }
15064
15065   /* Construct the API message */
15066   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15067   mp->sw_if_index = ntohl (sw_if_index);
15068   mp->enable_disable = enable_disable;
15069
15070   /* send it... */
15071   S (mp);
15072   /* Wait for the reply */
15073   W (ret);
15074   return ret;
15075 }
15076
15077 static int
15078 api_cop_whitelist_enable_disable (vat_main_t * vam)
15079 {
15080   unformat_input_t *line_input = vam->input;
15081   vl_api_cop_whitelist_enable_disable_t *mp;
15082   u32 sw_if_index = ~0;
15083   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15084   u32 fib_id = 0;
15085   int ret;
15086
15087   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (line_input, "ip4"))
15090         ip4 = 1;
15091       else if (unformat (line_input, "ip6"))
15092         ip6 = 1;
15093       else if (unformat (line_input, "default"))
15094         default_cop = 1;
15095       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15096                          vam, &sw_if_index))
15097         ;
15098       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15099         ;
15100       else if (unformat (line_input, "fib-id %d", &fib_id))
15101         ;
15102       else
15103         break;
15104     }
15105
15106   if (sw_if_index == ~0)
15107     {
15108       errmsg ("missing interface name or sw_if_index");
15109       return -99;
15110     }
15111
15112   /* Construct the API message */
15113   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15114   mp->sw_if_index = ntohl (sw_if_index);
15115   mp->fib_id = ntohl (fib_id);
15116   mp->ip4 = ip4;
15117   mp->ip6 = ip6;
15118   mp->default_cop = default_cop;
15119
15120   /* send it... */
15121   S (mp);
15122   /* Wait for the reply */
15123   W (ret);
15124   return ret;
15125 }
15126
15127 static int
15128 api_get_node_graph (vat_main_t * vam)
15129 {
15130   vl_api_get_node_graph_t *mp;
15131   int ret;
15132
15133   M (GET_NODE_GRAPH, mp);
15134
15135   /* send it... */
15136   S (mp);
15137   /* Wait for the reply */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 /* *INDENT-OFF* */
15143 /** Used for parsing LISP eids */
15144 typedef CLIB_PACKED(struct{
15145   u8 addr[16];   /**< eid address */
15146   u32 len;       /**< prefix length if IP */
15147   u8 type;      /**< type of eid */
15148 }) lisp_eid_vat_t;
15149 /* *INDENT-ON* */
15150
15151 static uword
15152 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15153 {
15154   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15155
15156   clib_memset (a, 0, sizeof (a[0]));
15157
15158   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15159     {
15160       a->type = 0;              /* ipv4 type */
15161     }
15162   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15163     {
15164       a->type = 1;              /* ipv6 type */
15165     }
15166   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15167     {
15168       a->type = 2;              /* mac type */
15169     }
15170   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15171     {
15172       a->type = 3;              /* NSH type */
15173       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15174       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15175     }
15176   else
15177     {
15178       return 0;
15179     }
15180
15181   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15182     {
15183       return 0;
15184     }
15185
15186   return 1;
15187 }
15188
15189 static int
15190 lisp_eid_size_vat (u8 type)
15191 {
15192   switch (type)
15193     {
15194     case 0:
15195       return 4;
15196     case 1:
15197       return 16;
15198     case 2:
15199       return 6;
15200     case 3:
15201       return 5;
15202     }
15203   return 0;
15204 }
15205
15206 static void
15207 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15208 {
15209   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15210 }
15211
15212 static int
15213 api_one_add_del_locator_set (vat_main_t * vam)
15214 {
15215   unformat_input_t *input = vam->input;
15216   vl_api_one_add_del_locator_set_t *mp;
15217   u8 is_add = 1;
15218   u8 *locator_set_name = NULL;
15219   u8 locator_set_name_set = 0;
15220   vl_api_local_locator_t locator, *locators = 0;
15221   u32 sw_if_index, priority, weight;
15222   u32 data_len = 0;
15223
15224   int ret;
15225   /* Parse args required to build the message */
15226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (input, "del"))
15229         {
15230           is_add = 0;
15231         }
15232       else if (unformat (input, "locator-set %s", &locator_set_name))
15233         {
15234           locator_set_name_set = 1;
15235         }
15236       else if (unformat (input, "sw_if_index %u p %u w %u",
15237                          &sw_if_index, &priority, &weight))
15238         {
15239           locator.sw_if_index = htonl (sw_if_index);
15240           locator.priority = priority;
15241           locator.weight = weight;
15242           vec_add1 (locators, locator);
15243         }
15244       else
15245         if (unformat
15246             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15247              &sw_if_index, &priority, &weight))
15248         {
15249           locator.sw_if_index = htonl (sw_if_index);
15250           locator.priority = priority;
15251           locator.weight = weight;
15252           vec_add1 (locators, locator);
15253         }
15254       else
15255         break;
15256     }
15257
15258   if (locator_set_name_set == 0)
15259     {
15260       errmsg ("missing locator-set name");
15261       vec_free (locators);
15262       return -99;
15263     }
15264
15265   if (vec_len (locator_set_name) > 64)
15266     {
15267       errmsg ("locator-set name too long");
15268       vec_free (locator_set_name);
15269       vec_free (locators);
15270       return -99;
15271     }
15272   vec_add1 (locator_set_name, 0);
15273
15274   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15275
15276   /* Construct the API message */
15277   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15278
15279   mp->is_add = is_add;
15280   clib_memcpy (mp->locator_set_name, locator_set_name,
15281                vec_len (locator_set_name));
15282   vec_free (locator_set_name);
15283
15284   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15285   if (locators)
15286     clib_memcpy (mp->locators, locators, data_len);
15287   vec_free (locators);
15288
15289   /* send it... */
15290   S (mp);
15291
15292   /* Wait for a reply... */
15293   W (ret);
15294   return ret;
15295 }
15296
15297 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15298
15299 static int
15300 api_one_add_del_locator (vat_main_t * vam)
15301 {
15302   unformat_input_t *input = vam->input;
15303   vl_api_one_add_del_locator_t *mp;
15304   u32 tmp_if_index = ~0;
15305   u32 sw_if_index = ~0;
15306   u8 sw_if_index_set = 0;
15307   u8 sw_if_index_if_name_set = 0;
15308   u32 priority = ~0;
15309   u8 priority_set = 0;
15310   u32 weight = ~0;
15311   u8 weight_set = 0;
15312   u8 is_add = 1;
15313   u8 *locator_set_name = NULL;
15314   u8 locator_set_name_set = 0;
15315   int ret;
15316
15317   /* Parse args required to build the message */
15318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15319     {
15320       if (unformat (input, "del"))
15321         {
15322           is_add = 0;
15323         }
15324       else if (unformat (input, "locator-set %s", &locator_set_name))
15325         {
15326           locator_set_name_set = 1;
15327         }
15328       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15329                          &tmp_if_index))
15330         {
15331           sw_if_index_if_name_set = 1;
15332           sw_if_index = tmp_if_index;
15333         }
15334       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15335         {
15336           sw_if_index_set = 1;
15337           sw_if_index = tmp_if_index;
15338         }
15339       else if (unformat (input, "p %d", &priority))
15340         {
15341           priority_set = 1;
15342         }
15343       else if (unformat (input, "w %d", &weight))
15344         {
15345           weight_set = 1;
15346         }
15347       else
15348         break;
15349     }
15350
15351   if (locator_set_name_set == 0)
15352     {
15353       errmsg ("missing locator-set name");
15354       return -99;
15355     }
15356
15357   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15358     {
15359       errmsg ("missing sw_if_index");
15360       vec_free (locator_set_name);
15361       return -99;
15362     }
15363
15364   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15365     {
15366       errmsg ("cannot use both params interface name and sw_if_index");
15367       vec_free (locator_set_name);
15368       return -99;
15369     }
15370
15371   if (priority_set == 0)
15372     {
15373       errmsg ("missing locator-set priority");
15374       vec_free (locator_set_name);
15375       return -99;
15376     }
15377
15378   if (weight_set == 0)
15379     {
15380       errmsg ("missing locator-set weight");
15381       vec_free (locator_set_name);
15382       return -99;
15383     }
15384
15385   if (vec_len (locator_set_name) > 64)
15386     {
15387       errmsg ("locator-set name too long");
15388       vec_free (locator_set_name);
15389       return -99;
15390     }
15391   vec_add1 (locator_set_name, 0);
15392
15393   /* Construct the API message */
15394   M (ONE_ADD_DEL_LOCATOR, mp);
15395
15396   mp->is_add = is_add;
15397   mp->sw_if_index = ntohl (sw_if_index);
15398   mp->priority = priority;
15399   mp->weight = weight;
15400   clib_memcpy (mp->locator_set_name, locator_set_name,
15401                vec_len (locator_set_name));
15402   vec_free (locator_set_name);
15403
15404   /* send it... */
15405   S (mp);
15406
15407   /* Wait for a reply... */
15408   W (ret);
15409   return ret;
15410 }
15411
15412 #define api_lisp_add_del_locator api_one_add_del_locator
15413
15414 uword
15415 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15416 {
15417   u32 *key_id = va_arg (*args, u32 *);
15418   u8 *s = 0;
15419
15420   if (unformat (input, "%s", &s))
15421     {
15422       if (!strcmp ((char *) s, "sha1"))
15423         key_id[0] = HMAC_SHA_1_96;
15424       else if (!strcmp ((char *) s, "sha256"))
15425         key_id[0] = HMAC_SHA_256_128;
15426       else
15427         {
15428           clib_warning ("invalid key_id: '%s'", s);
15429           key_id[0] = HMAC_NO_KEY;
15430         }
15431     }
15432   else
15433     return 0;
15434
15435   vec_free (s);
15436   return 1;
15437 }
15438
15439 static int
15440 api_one_add_del_local_eid (vat_main_t * vam)
15441 {
15442   unformat_input_t *input = vam->input;
15443   vl_api_one_add_del_local_eid_t *mp;
15444   u8 is_add = 1;
15445   u8 eid_set = 0;
15446   lisp_eid_vat_t _eid, *eid = &_eid;
15447   u8 *locator_set_name = 0;
15448   u8 locator_set_name_set = 0;
15449   u32 vni = 0;
15450   u16 key_id = 0;
15451   u8 *key = 0;
15452   int ret;
15453
15454   /* Parse args required to build the message */
15455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15456     {
15457       if (unformat (input, "del"))
15458         {
15459           is_add = 0;
15460         }
15461       else if (unformat (input, "vni %d", &vni))
15462         {
15463           ;
15464         }
15465       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15466         {
15467           eid_set = 1;
15468         }
15469       else if (unformat (input, "locator-set %s", &locator_set_name))
15470         {
15471           locator_set_name_set = 1;
15472         }
15473       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15474         ;
15475       else if (unformat (input, "secret-key %_%v%_", &key))
15476         ;
15477       else
15478         break;
15479     }
15480
15481   if (locator_set_name_set == 0)
15482     {
15483       errmsg ("missing locator-set name");
15484       return -99;
15485     }
15486
15487   if (0 == eid_set)
15488     {
15489       errmsg ("EID address not set!");
15490       vec_free (locator_set_name);
15491       return -99;
15492     }
15493
15494   if (key && (0 == key_id))
15495     {
15496       errmsg ("invalid key_id!");
15497       return -99;
15498     }
15499
15500   if (vec_len (key) > 64)
15501     {
15502       errmsg ("key too long");
15503       vec_free (key);
15504       return -99;
15505     }
15506
15507   if (vec_len (locator_set_name) > 64)
15508     {
15509       errmsg ("locator-set name too long");
15510       vec_free (locator_set_name);
15511       return -99;
15512     }
15513   vec_add1 (locator_set_name, 0);
15514
15515   /* Construct the API message */
15516   M (ONE_ADD_DEL_LOCAL_EID, mp);
15517
15518   mp->is_add = is_add;
15519   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15520   mp->eid_type = eid->type;
15521   mp->prefix_len = eid->len;
15522   mp->vni = clib_host_to_net_u32 (vni);
15523   mp->key_id = clib_host_to_net_u16 (key_id);
15524   clib_memcpy (mp->locator_set_name, locator_set_name,
15525                vec_len (locator_set_name));
15526   clib_memcpy (mp->key, key, vec_len (key));
15527
15528   vec_free (locator_set_name);
15529   vec_free (key);
15530
15531   /* send it... */
15532   S (mp);
15533
15534   /* Wait for a reply... */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15540
15541 static int
15542 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15543 {
15544   u32 dp_table = 0, vni = 0;;
15545   unformat_input_t *input = vam->input;
15546   vl_api_gpe_add_del_fwd_entry_t *mp;
15547   u8 is_add = 1;
15548   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15549   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15550   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15551   u32 action = ~0, w;
15552   ip4_address_t rmt_rloc4, lcl_rloc4;
15553   ip6_address_t rmt_rloc6, lcl_rloc6;
15554   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15555   int ret;
15556
15557   clib_memset (&rloc, 0, sizeof (rloc));
15558
15559   /* Parse args required to build the message */
15560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15561     {
15562       if (unformat (input, "del"))
15563         is_add = 0;
15564       else if (unformat (input, "add"))
15565         is_add = 1;
15566       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15567         {
15568           rmt_eid_set = 1;
15569         }
15570       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15571         {
15572           lcl_eid_set = 1;
15573         }
15574       else if (unformat (input, "vrf %d", &dp_table))
15575         ;
15576       else if (unformat (input, "bd %d", &dp_table))
15577         ;
15578       else if (unformat (input, "vni %d", &vni))
15579         ;
15580       else if (unformat (input, "w %d", &w))
15581         {
15582           if (!curr_rloc)
15583             {
15584               errmsg ("No RLOC configured for setting priority/weight!");
15585               return -99;
15586             }
15587           curr_rloc->weight = w;
15588         }
15589       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15590                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15591         {
15592           rloc.is_ip4 = 1;
15593
15594           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15595           rloc.weight = 0;
15596           vec_add1 (lcl_locs, rloc);
15597
15598           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15599           vec_add1 (rmt_locs, rloc);
15600           /* weight saved in rmt loc */
15601           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15602         }
15603       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15604                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15605         {
15606           rloc.is_ip4 = 0;
15607           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15608           rloc.weight = 0;
15609           vec_add1 (lcl_locs, rloc);
15610
15611           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15612           vec_add1 (rmt_locs, rloc);
15613           /* weight saved in rmt loc */
15614           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15615         }
15616       else if (unformat (input, "action %d", &action))
15617         {
15618           ;
15619         }
15620       else
15621         {
15622           clib_warning ("parse error '%U'", format_unformat_error, input);
15623           return -99;
15624         }
15625     }
15626
15627   if (!rmt_eid_set)
15628     {
15629       errmsg ("remote eid addresses not set");
15630       return -99;
15631     }
15632
15633   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15634     {
15635       errmsg ("eid types don't match");
15636       return -99;
15637     }
15638
15639   if (0 == rmt_locs && (u32) ~ 0 == action)
15640     {
15641       errmsg ("action not set for negative mapping");
15642       return -99;
15643     }
15644
15645   /* Construct the API message */
15646   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15647       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15648
15649   mp->is_add = is_add;
15650   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15651   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15652   mp->eid_type = rmt_eid->type;
15653   mp->dp_table = clib_host_to_net_u32 (dp_table);
15654   mp->vni = clib_host_to_net_u32 (vni);
15655   mp->rmt_len = rmt_eid->len;
15656   mp->lcl_len = lcl_eid->len;
15657   mp->action = action;
15658
15659   if (0 != rmt_locs && 0 != lcl_locs)
15660     {
15661       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15662       clib_memcpy (mp->locs, lcl_locs,
15663                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15664
15665       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15666       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15667                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15668     }
15669   vec_free (lcl_locs);
15670   vec_free (rmt_locs);
15671
15672   /* send it... */
15673   S (mp);
15674
15675   /* Wait for a reply... */
15676   W (ret);
15677   return ret;
15678 }
15679
15680 static int
15681 api_one_add_del_map_server (vat_main_t * vam)
15682 {
15683   unformat_input_t *input = vam->input;
15684   vl_api_one_add_del_map_server_t *mp;
15685   u8 is_add = 1;
15686   u8 ipv4_set = 0;
15687   u8 ipv6_set = 0;
15688   ip4_address_t ipv4;
15689   ip6_address_t ipv6;
15690   int ret;
15691
15692   /* Parse args required to build the message */
15693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (input, "del"))
15696         {
15697           is_add = 0;
15698         }
15699       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15700         {
15701           ipv4_set = 1;
15702         }
15703       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15704         {
15705           ipv6_set = 1;
15706         }
15707       else
15708         break;
15709     }
15710
15711   if (ipv4_set && ipv6_set)
15712     {
15713       errmsg ("both eid v4 and v6 addresses set");
15714       return -99;
15715     }
15716
15717   if (!ipv4_set && !ipv6_set)
15718     {
15719       errmsg ("eid addresses not set");
15720       return -99;
15721     }
15722
15723   /* Construct the API message */
15724   M (ONE_ADD_DEL_MAP_SERVER, mp);
15725
15726   mp->is_add = is_add;
15727   if (ipv6_set)
15728     {
15729       mp->is_ipv6 = 1;
15730       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15731     }
15732   else
15733     {
15734       mp->is_ipv6 = 0;
15735       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15736     }
15737
15738   /* send it... */
15739   S (mp);
15740
15741   /* Wait for a reply... */
15742   W (ret);
15743   return ret;
15744 }
15745
15746 #define api_lisp_add_del_map_server api_one_add_del_map_server
15747
15748 static int
15749 api_one_add_del_map_resolver (vat_main_t * vam)
15750 {
15751   unformat_input_t *input = vam->input;
15752   vl_api_one_add_del_map_resolver_t *mp;
15753   u8 is_add = 1;
15754   u8 ipv4_set = 0;
15755   u8 ipv6_set = 0;
15756   ip4_address_t ipv4;
15757   ip6_address_t ipv6;
15758   int ret;
15759
15760   /* Parse args required to build the message */
15761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15762     {
15763       if (unformat (input, "del"))
15764         {
15765           is_add = 0;
15766         }
15767       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15768         {
15769           ipv4_set = 1;
15770         }
15771       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15772         {
15773           ipv6_set = 1;
15774         }
15775       else
15776         break;
15777     }
15778
15779   if (ipv4_set && ipv6_set)
15780     {
15781       errmsg ("both eid v4 and v6 addresses set");
15782       return -99;
15783     }
15784
15785   if (!ipv4_set && !ipv6_set)
15786     {
15787       errmsg ("eid addresses not set");
15788       return -99;
15789     }
15790
15791   /* Construct the API message */
15792   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15793
15794   mp->is_add = is_add;
15795   if (ipv6_set)
15796     {
15797       mp->is_ipv6 = 1;
15798       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15799     }
15800   else
15801     {
15802       mp->is_ipv6 = 0;
15803       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15804     }
15805
15806   /* send it... */
15807   S (mp);
15808
15809   /* Wait for a reply... */
15810   W (ret);
15811   return ret;
15812 }
15813
15814 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15815
15816 static int
15817 api_lisp_gpe_enable_disable (vat_main_t * vam)
15818 {
15819   unformat_input_t *input = vam->input;
15820   vl_api_gpe_enable_disable_t *mp;
15821   u8 is_set = 0;
15822   u8 is_en = 1;
15823   int ret;
15824
15825   /* Parse args required to build the message */
15826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15827     {
15828       if (unformat (input, "enable"))
15829         {
15830           is_set = 1;
15831           is_en = 1;
15832         }
15833       else if (unformat (input, "disable"))
15834         {
15835           is_set = 1;
15836           is_en = 0;
15837         }
15838       else
15839         break;
15840     }
15841
15842   if (is_set == 0)
15843     {
15844       errmsg ("Value not set");
15845       return -99;
15846     }
15847
15848   /* Construct the API message */
15849   M (GPE_ENABLE_DISABLE, mp);
15850
15851   mp->is_en = is_en;
15852
15853   /* send it... */
15854   S (mp);
15855
15856   /* Wait for a reply... */
15857   W (ret);
15858   return ret;
15859 }
15860
15861 static int
15862 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15863 {
15864   unformat_input_t *input = vam->input;
15865   vl_api_one_rloc_probe_enable_disable_t *mp;
15866   u8 is_set = 0;
15867   u8 is_en = 0;
15868   int ret;
15869
15870   /* Parse args required to build the message */
15871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15872     {
15873       if (unformat (input, "enable"))
15874         {
15875           is_set = 1;
15876           is_en = 1;
15877         }
15878       else if (unformat (input, "disable"))
15879         is_set = 1;
15880       else
15881         break;
15882     }
15883
15884   if (!is_set)
15885     {
15886       errmsg ("Value not set");
15887       return -99;
15888     }
15889
15890   /* Construct the API message */
15891   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15892
15893   mp->is_enabled = is_en;
15894
15895   /* send it... */
15896   S (mp);
15897
15898   /* Wait for a reply... */
15899   W (ret);
15900   return ret;
15901 }
15902
15903 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15904
15905 static int
15906 api_one_map_register_enable_disable (vat_main_t * vam)
15907 {
15908   unformat_input_t *input = vam->input;
15909   vl_api_one_map_register_enable_disable_t *mp;
15910   u8 is_set = 0;
15911   u8 is_en = 0;
15912   int ret;
15913
15914   /* Parse args required to build the message */
15915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15916     {
15917       if (unformat (input, "enable"))
15918         {
15919           is_set = 1;
15920           is_en = 1;
15921         }
15922       else if (unformat (input, "disable"))
15923         is_set = 1;
15924       else
15925         break;
15926     }
15927
15928   if (!is_set)
15929     {
15930       errmsg ("Value not set");
15931       return -99;
15932     }
15933
15934   /* Construct the API message */
15935   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15936
15937   mp->is_enabled = is_en;
15938
15939   /* send it... */
15940   S (mp);
15941
15942   /* Wait for a reply... */
15943   W (ret);
15944   return ret;
15945 }
15946
15947 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15948
15949 static int
15950 api_one_enable_disable (vat_main_t * vam)
15951 {
15952   unformat_input_t *input = vam->input;
15953   vl_api_one_enable_disable_t *mp;
15954   u8 is_set = 0;
15955   u8 is_en = 0;
15956   int ret;
15957
15958   /* Parse args required to build the message */
15959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15960     {
15961       if (unformat (input, "enable"))
15962         {
15963           is_set = 1;
15964           is_en = 1;
15965         }
15966       else if (unformat (input, "disable"))
15967         {
15968           is_set = 1;
15969         }
15970       else
15971         break;
15972     }
15973
15974   if (!is_set)
15975     {
15976       errmsg ("Value not set");
15977       return -99;
15978     }
15979
15980   /* Construct the API message */
15981   M (ONE_ENABLE_DISABLE, mp);
15982
15983   mp->is_en = is_en;
15984
15985   /* send it... */
15986   S (mp);
15987
15988   /* Wait for a reply... */
15989   W (ret);
15990   return ret;
15991 }
15992
15993 #define api_lisp_enable_disable api_one_enable_disable
15994
15995 static int
15996 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15997 {
15998   unformat_input_t *input = vam->input;
15999   vl_api_one_enable_disable_xtr_mode_t *mp;
16000   u8 is_set = 0;
16001   u8 is_en = 0;
16002   int ret;
16003
16004   /* Parse args required to build the message */
16005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16006     {
16007       if (unformat (input, "enable"))
16008         {
16009           is_set = 1;
16010           is_en = 1;
16011         }
16012       else if (unformat (input, "disable"))
16013         {
16014           is_set = 1;
16015         }
16016       else
16017         break;
16018     }
16019
16020   if (!is_set)
16021     {
16022       errmsg ("Value not set");
16023       return -99;
16024     }
16025
16026   /* Construct the API message */
16027   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16028
16029   mp->is_en = is_en;
16030
16031   /* send it... */
16032   S (mp);
16033
16034   /* Wait for a reply... */
16035   W (ret);
16036   return ret;
16037 }
16038
16039 static int
16040 api_one_show_xtr_mode (vat_main_t * vam)
16041 {
16042   vl_api_one_show_xtr_mode_t *mp;
16043   int ret;
16044
16045   /* Construct the API message */
16046   M (ONE_SHOW_XTR_MODE, mp);
16047
16048   /* send it... */
16049   S (mp);
16050
16051   /* Wait for a reply... */
16052   W (ret);
16053   return ret;
16054 }
16055
16056 static int
16057 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16058 {
16059   unformat_input_t *input = vam->input;
16060   vl_api_one_enable_disable_pitr_mode_t *mp;
16061   u8 is_set = 0;
16062   u8 is_en = 0;
16063   int ret;
16064
16065   /* Parse args required to build the message */
16066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16067     {
16068       if (unformat (input, "enable"))
16069         {
16070           is_set = 1;
16071           is_en = 1;
16072         }
16073       else if (unformat (input, "disable"))
16074         {
16075           is_set = 1;
16076         }
16077       else
16078         break;
16079     }
16080
16081   if (!is_set)
16082     {
16083       errmsg ("Value not set");
16084       return -99;
16085     }
16086
16087   /* Construct the API message */
16088   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16089
16090   mp->is_en = is_en;
16091
16092   /* send it... */
16093   S (mp);
16094
16095   /* Wait for a reply... */
16096   W (ret);
16097   return ret;
16098 }
16099
16100 static int
16101 api_one_show_pitr_mode (vat_main_t * vam)
16102 {
16103   vl_api_one_show_pitr_mode_t *mp;
16104   int ret;
16105
16106   /* Construct the API message */
16107   M (ONE_SHOW_PITR_MODE, mp);
16108
16109   /* send it... */
16110   S (mp);
16111
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_one_enable_disable_petr_mode (vat_main_t * vam)
16119 {
16120   unformat_input_t *input = vam->input;
16121   vl_api_one_enable_disable_petr_mode_t *mp;
16122   u8 is_set = 0;
16123   u8 is_en = 0;
16124   int ret;
16125
16126   /* Parse args required to build the message */
16127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (input, "enable"))
16130         {
16131           is_set = 1;
16132           is_en = 1;
16133         }
16134       else if (unformat (input, "disable"))
16135         {
16136           is_set = 1;
16137         }
16138       else
16139         break;
16140     }
16141
16142   if (!is_set)
16143     {
16144       errmsg ("Value not set");
16145       return -99;
16146     }
16147
16148   /* Construct the API message */
16149   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16150
16151   mp->is_en = is_en;
16152
16153   /* send it... */
16154   S (mp);
16155
16156   /* Wait for a reply... */
16157   W (ret);
16158   return ret;
16159 }
16160
16161 static int
16162 api_one_show_petr_mode (vat_main_t * vam)
16163 {
16164   vl_api_one_show_petr_mode_t *mp;
16165   int ret;
16166
16167   /* Construct the API message */
16168   M (ONE_SHOW_PETR_MODE, mp);
16169
16170   /* send it... */
16171   S (mp);
16172
16173   /* Wait for a reply... */
16174   W (ret);
16175   return ret;
16176 }
16177
16178 static int
16179 api_show_one_map_register_state (vat_main_t * vam)
16180 {
16181   vl_api_show_one_map_register_state_t *mp;
16182   int ret;
16183
16184   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16185
16186   /* send */
16187   S (mp);
16188
16189   /* wait for reply */
16190   W (ret);
16191   return ret;
16192 }
16193
16194 #define api_show_lisp_map_register_state api_show_one_map_register_state
16195
16196 static int
16197 api_show_one_rloc_probe_state (vat_main_t * vam)
16198 {
16199   vl_api_show_one_rloc_probe_state_t *mp;
16200   int ret;
16201
16202   M (SHOW_ONE_RLOC_PROBE_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_rloc_probe_state api_show_one_rloc_probe_state
16213
16214 static int
16215 api_one_add_del_ndp_entry (vat_main_t * vam)
16216 {
16217   vl_api_one_add_del_ndp_entry_t *mp;
16218   unformat_input_t *input = vam->input;
16219   u8 is_add = 1;
16220   u8 mac_set = 0;
16221   u8 bd_set = 0;
16222   u8 ip_set = 0;
16223   u8 mac[6] = { 0, };
16224   u8 ip6[16] = { 0, };
16225   u32 bd = ~0;
16226   int ret;
16227
16228   /* Parse args required to build the message */
16229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16230     {
16231       if (unformat (input, "del"))
16232         is_add = 0;
16233       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16234         mac_set = 1;
16235       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16236         ip_set = 1;
16237       else if (unformat (input, "bd %d", &bd))
16238         bd_set = 1;
16239       else
16240         {
16241           errmsg ("parse error '%U'", format_unformat_error, input);
16242           return -99;
16243         }
16244     }
16245
16246   if (!bd_set || !ip_set || (!mac_set && is_add))
16247     {
16248       errmsg ("Missing BD, IP or MAC!");
16249       return -99;
16250     }
16251
16252   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16253   mp->is_add = is_add;
16254   clib_memcpy (mp->mac, mac, 6);
16255   mp->bd = clib_host_to_net_u32 (bd);
16256   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16257
16258   /* send */
16259   S (mp);
16260
16261   /* wait for reply */
16262   W (ret);
16263   return ret;
16264 }
16265
16266 static int
16267 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16268 {
16269   vl_api_one_add_del_l2_arp_entry_t *mp;
16270   unformat_input_t *input = vam->input;
16271   u8 is_add = 1;
16272   u8 mac_set = 0;
16273   u8 bd_set = 0;
16274   u8 ip_set = 0;
16275   u8 mac[6] = { 0, };
16276   u32 ip4 = 0, bd = ~0;
16277   int ret;
16278
16279   /* Parse args required to build the message */
16280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16281     {
16282       if (unformat (input, "del"))
16283         is_add = 0;
16284       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16285         mac_set = 1;
16286       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16287         ip_set = 1;
16288       else if (unformat (input, "bd %d", &bd))
16289         bd_set = 1;
16290       else
16291         {
16292           errmsg ("parse error '%U'", format_unformat_error, input);
16293           return -99;
16294         }
16295     }
16296
16297   if (!bd_set || !ip_set || (!mac_set && is_add))
16298     {
16299       errmsg ("Missing BD, IP or MAC!");
16300       return -99;
16301     }
16302
16303   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16304   mp->is_add = is_add;
16305   clib_memcpy (mp->mac, mac, 6);
16306   mp->bd = clib_host_to_net_u32 (bd);
16307   mp->ip4 = ip4;
16308
16309   /* send */
16310   S (mp);
16311
16312   /* wait for reply */
16313   W (ret);
16314   return ret;
16315 }
16316
16317 static int
16318 api_one_ndp_bd_get (vat_main_t * vam)
16319 {
16320   vl_api_one_ndp_bd_get_t *mp;
16321   int ret;
16322
16323   M (ONE_NDP_BD_GET, mp);
16324
16325   /* send */
16326   S (mp);
16327
16328   /* wait for reply */
16329   W (ret);
16330   return ret;
16331 }
16332
16333 static int
16334 api_one_ndp_entries_get (vat_main_t * vam)
16335 {
16336   vl_api_one_ndp_entries_get_t *mp;
16337   unformat_input_t *input = vam->input;
16338   u8 bd_set = 0;
16339   u32 bd = ~0;
16340   int ret;
16341
16342   /* Parse args required to build the message */
16343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (input, "bd %d", &bd))
16346         bd_set = 1;
16347       else
16348         {
16349           errmsg ("parse error '%U'", format_unformat_error, input);
16350           return -99;
16351         }
16352     }
16353
16354   if (!bd_set)
16355     {
16356       errmsg ("Expected bridge domain!");
16357       return -99;
16358     }
16359
16360   M (ONE_NDP_ENTRIES_GET, mp);
16361   mp->bd = clib_host_to_net_u32 (bd);
16362
16363   /* send */
16364   S (mp);
16365
16366   /* wait for reply */
16367   W (ret);
16368   return ret;
16369 }
16370
16371 static int
16372 api_one_l2_arp_bd_get (vat_main_t * vam)
16373 {
16374   vl_api_one_l2_arp_bd_get_t *mp;
16375   int ret;
16376
16377   M (ONE_L2_ARP_BD_GET, mp);
16378
16379   /* send */
16380   S (mp);
16381
16382   /* wait for reply */
16383   W (ret);
16384   return ret;
16385 }
16386
16387 static int
16388 api_one_l2_arp_entries_get (vat_main_t * vam)
16389 {
16390   vl_api_one_l2_arp_entries_get_t *mp;
16391   unformat_input_t *input = vam->input;
16392   u8 bd_set = 0;
16393   u32 bd = ~0;
16394   int ret;
16395
16396   /* Parse args required to build the message */
16397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16398     {
16399       if (unformat (input, "bd %d", &bd))
16400         bd_set = 1;
16401       else
16402         {
16403           errmsg ("parse error '%U'", format_unformat_error, input);
16404           return -99;
16405         }
16406     }
16407
16408   if (!bd_set)
16409     {
16410       errmsg ("Expected bridge domain!");
16411       return -99;
16412     }
16413
16414   M (ONE_L2_ARP_ENTRIES_GET, mp);
16415   mp->bd = clib_host_to_net_u32 (bd);
16416
16417   /* send */
16418   S (mp);
16419
16420   /* wait for reply */
16421   W (ret);
16422   return ret;
16423 }
16424
16425 static int
16426 api_one_stats_enable_disable (vat_main_t * vam)
16427 {
16428   vl_api_one_stats_enable_disable_t *mp;
16429   unformat_input_t *input = vam->input;
16430   u8 is_set = 0;
16431   u8 is_en = 0;
16432   int ret;
16433
16434   /* Parse args required to build the message */
16435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16436     {
16437       if (unformat (input, "enable"))
16438         {
16439           is_set = 1;
16440           is_en = 1;
16441         }
16442       else if (unformat (input, "disable"))
16443         {
16444           is_set = 1;
16445         }
16446       else
16447         break;
16448     }
16449
16450   if (!is_set)
16451     {
16452       errmsg ("Value not set");
16453       return -99;
16454     }
16455
16456   M (ONE_STATS_ENABLE_DISABLE, mp);
16457   mp->is_en = is_en;
16458
16459   /* send */
16460   S (mp);
16461
16462   /* wait for reply */
16463   W (ret);
16464   return ret;
16465 }
16466
16467 static int
16468 api_show_one_stats_enable_disable (vat_main_t * vam)
16469 {
16470   vl_api_show_one_stats_enable_disable_t *mp;
16471   int ret;
16472
16473   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16474
16475   /* send */
16476   S (mp);
16477
16478   /* wait for reply */
16479   W (ret);
16480   return ret;
16481 }
16482
16483 static int
16484 api_show_one_map_request_mode (vat_main_t * vam)
16485 {
16486   vl_api_show_one_map_request_mode_t *mp;
16487   int ret;
16488
16489   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16490
16491   /* send */
16492   S (mp);
16493
16494   /* wait for reply */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16500
16501 static int
16502 api_one_map_request_mode (vat_main_t * vam)
16503 {
16504   unformat_input_t *input = vam->input;
16505   vl_api_one_map_request_mode_t *mp;
16506   u8 mode = 0;
16507   int ret;
16508
16509   /* Parse args required to build the message */
16510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16511     {
16512       if (unformat (input, "dst-only"))
16513         mode = 0;
16514       else if (unformat (input, "src-dst"))
16515         mode = 1;
16516       else
16517         {
16518           errmsg ("parse error '%U'", format_unformat_error, input);
16519           return -99;
16520         }
16521     }
16522
16523   M (ONE_MAP_REQUEST_MODE, mp);
16524
16525   mp->mode = mode;
16526
16527   /* send */
16528   S (mp);
16529
16530   /* wait for reply */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 #define api_lisp_map_request_mode api_one_map_request_mode
16536
16537 /**
16538  * Enable/disable ONE proxy ITR.
16539  *
16540  * @param vam vpp API test context
16541  * @return return code
16542  */
16543 static int
16544 api_one_pitr_set_locator_set (vat_main_t * vam)
16545 {
16546   u8 ls_name_set = 0;
16547   unformat_input_t *input = vam->input;
16548   vl_api_one_pitr_set_locator_set_t *mp;
16549   u8 is_add = 1;
16550   u8 *ls_name = 0;
16551   int ret;
16552
16553   /* Parse args required to build the message */
16554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16555     {
16556       if (unformat (input, "del"))
16557         is_add = 0;
16558       else if (unformat (input, "locator-set %s", &ls_name))
16559         ls_name_set = 1;
16560       else
16561         {
16562           errmsg ("parse error '%U'", format_unformat_error, input);
16563           return -99;
16564         }
16565     }
16566
16567   if (!ls_name_set)
16568     {
16569       errmsg ("locator-set name not set!");
16570       return -99;
16571     }
16572
16573   M (ONE_PITR_SET_LOCATOR_SET, mp);
16574
16575   mp->is_add = is_add;
16576   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16577   vec_free (ls_name);
16578
16579   /* send */
16580   S (mp);
16581
16582   /* wait for reply */
16583   W (ret);
16584   return ret;
16585 }
16586
16587 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16588
16589 static int
16590 api_one_nsh_set_locator_set (vat_main_t * vam)
16591 {
16592   u8 ls_name_set = 0;
16593   unformat_input_t *input = vam->input;
16594   vl_api_one_nsh_set_locator_set_t *mp;
16595   u8 is_add = 1;
16596   u8 *ls_name = 0;
16597   int ret;
16598
16599   /* Parse args required to build the message */
16600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16601     {
16602       if (unformat (input, "del"))
16603         is_add = 0;
16604       else if (unformat (input, "ls %s", &ls_name))
16605         ls_name_set = 1;
16606       else
16607         {
16608           errmsg ("parse error '%U'", format_unformat_error, input);
16609           return -99;
16610         }
16611     }
16612
16613   if (!ls_name_set && is_add)
16614     {
16615       errmsg ("locator-set name not set!");
16616       return -99;
16617     }
16618
16619   M (ONE_NSH_SET_LOCATOR_SET, mp);
16620
16621   mp->is_add = is_add;
16622   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16623   vec_free (ls_name);
16624
16625   /* send */
16626   S (mp);
16627
16628   /* wait for reply */
16629   W (ret);
16630   return ret;
16631 }
16632
16633 static int
16634 api_show_one_pitr (vat_main_t * vam)
16635 {
16636   vl_api_show_one_pitr_t *mp;
16637   int ret;
16638
16639   if (!vam->json_output)
16640     {
16641       print (vam->ofp, "%=20s", "lisp status:");
16642     }
16643
16644   M (SHOW_ONE_PITR, mp);
16645   /* send it... */
16646   S (mp);
16647
16648   /* Wait for a reply... */
16649   W (ret);
16650   return ret;
16651 }
16652
16653 #define api_show_lisp_pitr api_show_one_pitr
16654
16655 static int
16656 api_one_use_petr (vat_main_t * vam)
16657 {
16658   unformat_input_t *input = vam->input;
16659   vl_api_one_use_petr_t *mp;
16660   u8 is_add = 0;
16661   ip_address_t ip;
16662   int ret;
16663
16664   clib_memset (&ip, 0, sizeof (ip));
16665
16666   /* Parse args required to build the message */
16667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16668     {
16669       if (unformat (input, "disable"))
16670         is_add = 0;
16671       else
16672         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16673         {
16674           is_add = 1;
16675           ip_addr_version (&ip) = IP4;
16676         }
16677       else
16678         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16679         {
16680           is_add = 1;
16681           ip_addr_version (&ip) = IP6;
16682         }
16683       else
16684         {
16685           errmsg ("parse error '%U'", format_unformat_error, input);
16686           return -99;
16687         }
16688     }
16689
16690   M (ONE_USE_PETR, mp);
16691
16692   mp->is_add = is_add;
16693   if (is_add)
16694     {
16695       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16696       if (mp->is_ip4)
16697         clib_memcpy (mp->address, &ip, 4);
16698       else
16699         clib_memcpy (mp->address, &ip, 16);
16700     }
16701
16702   /* send */
16703   S (mp);
16704
16705   /* wait for reply */
16706   W (ret);
16707   return ret;
16708 }
16709
16710 #define api_lisp_use_petr api_one_use_petr
16711
16712 static int
16713 api_show_one_nsh_mapping (vat_main_t * vam)
16714 {
16715   vl_api_show_one_use_petr_t *mp;
16716   int ret;
16717
16718   if (!vam->json_output)
16719     {
16720       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16721     }
16722
16723   M (SHOW_ONE_NSH_MAPPING, mp);
16724   /* send it... */
16725   S (mp);
16726
16727   /* Wait for a reply... */
16728   W (ret);
16729   return ret;
16730 }
16731
16732 static int
16733 api_show_one_use_petr (vat_main_t * vam)
16734 {
16735   vl_api_show_one_use_petr_t *mp;
16736   int ret;
16737
16738   if (!vam->json_output)
16739     {
16740       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16741     }
16742
16743   M (SHOW_ONE_USE_PETR, mp);
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define api_show_lisp_use_petr api_show_one_use_petr
16753
16754 /**
16755  * Add/delete mapping between vni and vrf
16756  */
16757 static int
16758 api_one_eid_table_add_del_map (vat_main_t * vam)
16759 {
16760   unformat_input_t *input = vam->input;
16761   vl_api_one_eid_table_add_del_map_t *mp;
16762   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16763   u32 vni, vrf, bd_index;
16764   int ret;
16765
16766   /* Parse args required to build the message */
16767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16768     {
16769       if (unformat (input, "del"))
16770         is_add = 0;
16771       else if (unformat (input, "vrf %d", &vrf))
16772         vrf_set = 1;
16773       else if (unformat (input, "bd_index %d", &bd_index))
16774         bd_index_set = 1;
16775       else if (unformat (input, "vni %d", &vni))
16776         vni_set = 1;
16777       else
16778         break;
16779     }
16780
16781   if (!vni_set || (!vrf_set && !bd_index_set))
16782     {
16783       errmsg ("missing arguments!");
16784       return -99;
16785     }
16786
16787   if (vrf_set && bd_index_set)
16788     {
16789       errmsg ("error: both vrf and bd entered!");
16790       return -99;
16791     }
16792
16793   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16794
16795   mp->is_add = is_add;
16796   mp->vni = htonl (vni);
16797   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16798   mp->is_l2 = bd_index_set;
16799
16800   /* send */
16801   S (mp);
16802
16803   /* wait for reply */
16804   W (ret);
16805   return ret;
16806 }
16807
16808 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16809
16810 uword
16811 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16812 {
16813   u32 *action = va_arg (*args, u32 *);
16814   u8 *s = 0;
16815
16816   if (unformat (input, "%s", &s))
16817     {
16818       if (!strcmp ((char *) s, "no-action"))
16819         action[0] = 0;
16820       else if (!strcmp ((char *) s, "natively-forward"))
16821         action[0] = 1;
16822       else if (!strcmp ((char *) s, "send-map-request"))
16823         action[0] = 2;
16824       else if (!strcmp ((char *) s, "drop"))
16825         action[0] = 3;
16826       else
16827         {
16828           clib_warning ("invalid action: '%s'", s);
16829           action[0] = 3;
16830         }
16831     }
16832   else
16833     return 0;
16834
16835   vec_free (s);
16836   return 1;
16837 }
16838
16839 /**
16840  * Add/del remote mapping to/from ONE control plane
16841  *
16842  * @param vam vpp API test context
16843  * @return return code
16844  */
16845 static int
16846 api_one_add_del_remote_mapping (vat_main_t * vam)
16847 {
16848   unformat_input_t *input = vam->input;
16849   vl_api_one_add_del_remote_mapping_t *mp;
16850   u32 vni = 0;
16851   lisp_eid_vat_t _eid, *eid = &_eid;
16852   lisp_eid_vat_t _seid, *seid = &_seid;
16853   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16854   u32 action = ~0, p, w, data_len;
16855   ip4_address_t rloc4;
16856   ip6_address_t rloc6;
16857   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16858   int ret;
16859
16860   clib_memset (&rloc, 0, sizeof (rloc));
16861
16862   /* Parse args required to build the message */
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "del-all"))
16866         {
16867           del_all = 1;
16868         }
16869       else if (unformat (input, "del"))
16870         {
16871           is_add = 0;
16872         }
16873       else if (unformat (input, "add"))
16874         {
16875           is_add = 1;
16876         }
16877       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16878         {
16879           eid_set = 1;
16880         }
16881       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16882         {
16883           seid_set = 1;
16884         }
16885       else if (unformat (input, "vni %d", &vni))
16886         {
16887           ;
16888         }
16889       else if (unformat (input, "p %d w %d", &p, &w))
16890         {
16891           if (!curr_rloc)
16892             {
16893               errmsg ("No RLOC configured for setting priority/weight!");
16894               return -99;
16895             }
16896           curr_rloc->priority = p;
16897           curr_rloc->weight = w;
16898         }
16899       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16900         {
16901           rloc.is_ip4 = 1;
16902           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16903           vec_add1 (rlocs, rloc);
16904           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16905         }
16906       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16907         {
16908           rloc.is_ip4 = 0;
16909           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16910           vec_add1 (rlocs, rloc);
16911           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16912         }
16913       else if (unformat (input, "action %U",
16914                          unformat_negative_mapping_action, &action))
16915         {
16916           ;
16917         }
16918       else
16919         {
16920           clib_warning ("parse error '%U'", format_unformat_error, input);
16921           return -99;
16922         }
16923     }
16924
16925   if (0 == eid_set)
16926     {
16927       errmsg ("missing params!");
16928       return -99;
16929     }
16930
16931   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16932     {
16933       errmsg ("no action set for negative map-reply!");
16934       return -99;
16935     }
16936
16937   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16938
16939   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16940   mp->is_add = is_add;
16941   mp->vni = htonl (vni);
16942   mp->action = (u8) action;
16943   mp->is_src_dst = seid_set;
16944   mp->eid_len = eid->len;
16945   mp->seid_len = seid->len;
16946   mp->del_all = del_all;
16947   mp->eid_type = eid->type;
16948   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16949   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16950
16951   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16952   clib_memcpy (mp->rlocs, rlocs, data_len);
16953   vec_free (rlocs);
16954
16955   /* send it... */
16956   S (mp);
16957
16958   /* Wait for a reply... */
16959   W (ret);
16960   return ret;
16961 }
16962
16963 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16964
16965 /**
16966  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16967  * forwarding entries in data-plane accordingly.
16968  *
16969  * @param vam vpp API test context
16970  * @return return code
16971  */
16972 static int
16973 api_one_add_del_adjacency (vat_main_t * vam)
16974 {
16975   unformat_input_t *input = vam->input;
16976   vl_api_one_add_del_adjacency_t *mp;
16977   u32 vni = 0;
16978   ip4_address_t leid4, reid4;
16979   ip6_address_t leid6, reid6;
16980   u8 reid_mac[6] = { 0 };
16981   u8 leid_mac[6] = { 0 };
16982   u8 reid_type, leid_type;
16983   u32 leid_len = 0, reid_len = 0, len;
16984   u8 is_add = 1;
16985   int ret;
16986
16987   leid_type = reid_type = (u8) ~ 0;
16988
16989   /* Parse args required to build the message */
16990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16991     {
16992       if (unformat (input, "del"))
16993         {
16994           is_add = 0;
16995         }
16996       else if (unformat (input, "add"))
16997         {
16998           is_add = 1;
16999         }
17000       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17001                          &reid4, &len))
17002         {
17003           reid_type = 0;        /* ipv4 */
17004           reid_len = len;
17005         }
17006       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17007                          &reid6, &len))
17008         {
17009           reid_type = 1;        /* ipv6 */
17010           reid_len = len;
17011         }
17012       else if (unformat (input, "reid %U", unformat_ethernet_address,
17013                          reid_mac))
17014         {
17015           reid_type = 2;        /* mac */
17016         }
17017       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17018                          &leid4, &len))
17019         {
17020           leid_type = 0;        /* ipv4 */
17021           leid_len = len;
17022         }
17023       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17024                          &leid6, &len))
17025         {
17026           leid_type = 1;        /* ipv6 */
17027           leid_len = len;
17028         }
17029       else if (unformat (input, "leid %U", unformat_ethernet_address,
17030                          leid_mac))
17031         {
17032           leid_type = 2;        /* mac */
17033         }
17034       else if (unformat (input, "vni %d", &vni))
17035         {
17036           ;
17037         }
17038       else
17039         {
17040           errmsg ("parse error '%U'", format_unformat_error, input);
17041           return -99;
17042         }
17043     }
17044
17045   if ((u8) ~ 0 == reid_type)
17046     {
17047       errmsg ("missing params!");
17048       return -99;
17049     }
17050
17051   if (leid_type != reid_type)
17052     {
17053       errmsg ("remote and local EIDs are of different types!");
17054       return -99;
17055     }
17056
17057   M (ONE_ADD_DEL_ADJACENCY, mp);
17058   mp->is_add = is_add;
17059   mp->vni = htonl (vni);
17060   mp->leid_len = leid_len;
17061   mp->reid_len = reid_len;
17062   mp->eid_type = reid_type;
17063
17064   switch (mp->eid_type)
17065     {
17066     case 0:
17067       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17068       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17069       break;
17070     case 1:
17071       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17072       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17073       break;
17074     case 2:
17075       clib_memcpy (mp->leid, leid_mac, 6);
17076       clib_memcpy (mp->reid, reid_mac, 6);
17077       break;
17078     default:
17079       errmsg ("unknown EID type %d!", mp->eid_type);
17080       return 0;
17081     }
17082
17083   /* send it... */
17084   S (mp);
17085
17086   /* Wait for a reply... */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17092
17093 uword
17094 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17095 {
17096   u32 *mode = va_arg (*args, u32 *);
17097
17098   if (unformat (input, "lisp"))
17099     *mode = 0;
17100   else if (unformat (input, "vxlan"))
17101     *mode = 1;
17102   else
17103     return 0;
17104
17105   return 1;
17106 }
17107
17108 static int
17109 api_gpe_get_encap_mode (vat_main_t * vam)
17110 {
17111   vl_api_gpe_get_encap_mode_t *mp;
17112   int ret;
17113
17114   /* Construct the API message */
17115   M (GPE_GET_ENCAP_MODE, mp);
17116
17117   /* send it... */
17118   S (mp);
17119
17120   /* Wait for a reply... */
17121   W (ret);
17122   return ret;
17123 }
17124
17125 static int
17126 api_gpe_set_encap_mode (vat_main_t * vam)
17127 {
17128   unformat_input_t *input = vam->input;
17129   vl_api_gpe_set_encap_mode_t *mp;
17130   int ret;
17131   u32 mode = 0;
17132
17133   /* Parse args required to build the message */
17134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17135     {
17136       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17137         ;
17138       else
17139         break;
17140     }
17141
17142   /* Construct the API message */
17143   M (GPE_SET_ENCAP_MODE, mp);
17144
17145   mp->mode = mode;
17146
17147   /* send it... */
17148   S (mp);
17149
17150   /* Wait for a reply... */
17151   W (ret);
17152   return ret;
17153 }
17154
17155 static int
17156 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17157 {
17158   unformat_input_t *input = vam->input;
17159   vl_api_gpe_add_del_iface_t *mp;
17160   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17161   u32 dp_table = 0, vni = 0;
17162   int ret;
17163
17164   /* Parse args required to build the message */
17165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17166     {
17167       if (unformat (input, "up"))
17168         {
17169           action_set = 1;
17170           is_add = 1;
17171         }
17172       else if (unformat (input, "down"))
17173         {
17174           action_set = 1;
17175           is_add = 0;
17176         }
17177       else if (unformat (input, "table_id %d", &dp_table))
17178         {
17179           dp_table_set = 1;
17180         }
17181       else if (unformat (input, "bd_id %d", &dp_table))
17182         {
17183           dp_table_set = 1;
17184           is_l2 = 1;
17185         }
17186       else if (unformat (input, "vni %d", &vni))
17187         {
17188           vni_set = 1;
17189         }
17190       else
17191         break;
17192     }
17193
17194   if (action_set == 0)
17195     {
17196       errmsg ("Action not set");
17197       return -99;
17198     }
17199   if (dp_table_set == 0 || vni_set == 0)
17200     {
17201       errmsg ("vni and dp_table must be set");
17202       return -99;
17203     }
17204
17205   /* Construct the API message */
17206   M (GPE_ADD_DEL_IFACE, mp);
17207
17208   mp->is_add = is_add;
17209   mp->dp_table = clib_host_to_net_u32 (dp_table);
17210   mp->is_l2 = is_l2;
17211   mp->vni = clib_host_to_net_u32 (vni);
17212
17213   /* send it... */
17214   S (mp);
17215
17216   /* Wait for a reply... */
17217   W (ret);
17218   return ret;
17219 }
17220
17221 static int
17222 api_one_map_register_fallback_threshold (vat_main_t * vam)
17223 {
17224   unformat_input_t *input = vam->input;
17225   vl_api_one_map_register_fallback_threshold_t *mp;
17226   u32 value = 0;
17227   u8 is_set = 0;
17228   int ret;
17229
17230   /* Parse args required to build the message */
17231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17232     {
17233       if (unformat (input, "%u", &value))
17234         is_set = 1;
17235       else
17236         {
17237           clib_warning ("parse error '%U'", format_unformat_error, input);
17238           return -99;
17239         }
17240     }
17241
17242   if (!is_set)
17243     {
17244       errmsg ("fallback threshold value is missing!");
17245       return -99;
17246     }
17247
17248   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17249   mp->value = clib_host_to_net_u32 (value);
17250
17251   /* send it... */
17252   S (mp);
17253
17254   /* Wait for a reply... */
17255   W (ret);
17256   return ret;
17257 }
17258
17259 static int
17260 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17261 {
17262   vl_api_show_one_map_register_fallback_threshold_t *mp;
17263   int ret;
17264
17265   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17266
17267   /* send it... */
17268   S (mp);
17269
17270   /* Wait for a reply... */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 uword
17276 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17277 {
17278   u32 *proto = va_arg (*args, u32 *);
17279
17280   if (unformat (input, "udp"))
17281     *proto = 1;
17282   else if (unformat (input, "api"))
17283     *proto = 2;
17284   else
17285     return 0;
17286
17287   return 1;
17288 }
17289
17290 static int
17291 api_one_set_transport_protocol (vat_main_t * vam)
17292 {
17293   unformat_input_t *input = vam->input;
17294   vl_api_one_set_transport_protocol_t *mp;
17295   u8 is_set = 0;
17296   u32 protocol = 0;
17297   int ret;
17298
17299   /* Parse args required to build the message */
17300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17301     {
17302       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17303         is_set = 1;
17304       else
17305         {
17306           clib_warning ("parse error '%U'", format_unformat_error, input);
17307           return -99;
17308         }
17309     }
17310
17311   if (!is_set)
17312     {
17313       errmsg ("Transport protocol missing!");
17314       return -99;
17315     }
17316
17317   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17318   mp->protocol = (u8) protocol;
17319
17320   /* send it... */
17321   S (mp);
17322
17323   /* Wait for a reply... */
17324   W (ret);
17325   return ret;
17326 }
17327
17328 static int
17329 api_one_get_transport_protocol (vat_main_t * vam)
17330 {
17331   vl_api_one_get_transport_protocol_t *mp;
17332   int ret;
17333
17334   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17335
17336   /* send it... */
17337   S (mp);
17338
17339   /* Wait for a reply... */
17340   W (ret);
17341   return ret;
17342 }
17343
17344 static int
17345 api_one_map_register_set_ttl (vat_main_t * vam)
17346 {
17347   unformat_input_t *input = vam->input;
17348   vl_api_one_map_register_set_ttl_t *mp;
17349   u32 ttl = 0;
17350   u8 is_set = 0;
17351   int ret;
17352
17353   /* Parse args required to build the message */
17354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17355     {
17356       if (unformat (input, "%u", &ttl))
17357         is_set = 1;
17358       else
17359         {
17360           clib_warning ("parse error '%U'", format_unformat_error, input);
17361           return -99;
17362         }
17363     }
17364
17365   if (!is_set)
17366     {
17367       errmsg ("TTL value missing!");
17368       return -99;
17369     }
17370
17371   M (ONE_MAP_REGISTER_SET_TTL, mp);
17372   mp->ttl = clib_host_to_net_u32 (ttl);
17373
17374   /* send it... */
17375   S (mp);
17376
17377   /* Wait for a reply... */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 static int
17383 api_show_one_map_register_ttl (vat_main_t * vam)
17384 {
17385   vl_api_show_one_map_register_ttl_t *mp;
17386   int ret;
17387
17388   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17389
17390   /* send it... */
17391   S (mp);
17392
17393   /* Wait for a reply... */
17394   W (ret);
17395   return ret;
17396 }
17397
17398 /**
17399  * Add/del map request itr rlocs from ONE control plane and updates
17400  *
17401  * @param vam vpp API test context
17402  * @return return code
17403  */
17404 static int
17405 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17406 {
17407   unformat_input_t *input = vam->input;
17408   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17409   u8 *locator_set_name = 0;
17410   u8 locator_set_name_set = 0;
17411   u8 is_add = 1;
17412   int ret;
17413
17414   /* Parse args required to build the message */
17415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17416     {
17417       if (unformat (input, "del"))
17418         {
17419           is_add = 0;
17420         }
17421       else if (unformat (input, "%_%v%_", &locator_set_name))
17422         {
17423           locator_set_name_set = 1;
17424         }
17425       else
17426         {
17427           clib_warning ("parse error '%U'", format_unformat_error, input);
17428           return -99;
17429         }
17430     }
17431
17432   if (is_add && !locator_set_name_set)
17433     {
17434       errmsg ("itr-rloc is not set!");
17435       return -99;
17436     }
17437
17438   if (is_add && vec_len (locator_set_name) > 64)
17439     {
17440       errmsg ("itr-rloc locator-set name too long");
17441       vec_free (locator_set_name);
17442       return -99;
17443     }
17444
17445   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17446   mp->is_add = is_add;
17447   if (is_add)
17448     {
17449       clib_memcpy (mp->locator_set_name, locator_set_name,
17450                    vec_len (locator_set_name));
17451     }
17452   else
17453     {
17454       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17455     }
17456   vec_free (locator_set_name);
17457
17458   /* send it... */
17459   S (mp);
17460
17461   /* Wait for a reply... */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17467
17468 static int
17469 api_one_locator_dump (vat_main_t * vam)
17470 {
17471   unformat_input_t *input = vam->input;
17472   vl_api_one_locator_dump_t *mp;
17473   vl_api_control_ping_t *mp_ping;
17474   u8 is_index_set = 0, is_name_set = 0;
17475   u8 *ls_name = 0;
17476   u32 ls_index = ~0;
17477   int ret;
17478
17479   /* Parse args required to build the message */
17480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17481     {
17482       if (unformat (input, "ls_name %_%v%_", &ls_name))
17483         {
17484           is_name_set = 1;
17485         }
17486       else if (unformat (input, "ls_index %d", &ls_index))
17487         {
17488           is_index_set = 1;
17489         }
17490       else
17491         {
17492           errmsg ("parse error '%U'", format_unformat_error, input);
17493           return -99;
17494         }
17495     }
17496
17497   if (!is_index_set && !is_name_set)
17498     {
17499       errmsg ("error: expected one of index or name!");
17500       return -99;
17501     }
17502
17503   if (is_index_set && is_name_set)
17504     {
17505       errmsg ("error: only one param expected!");
17506       return -99;
17507     }
17508
17509   if (vec_len (ls_name) > 62)
17510     {
17511       errmsg ("error: locator set name too long!");
17512       return -99;
17513     }
17514
17515   if (!vam->json_output)
17516     {
17517       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17518     }
17519
17520   M (ONE_LOCATOR_DUMP, mp);
17521   mp->is_index_set = is_index_set;
17522
17523   if (is_index_set)
17524     mp->ls_index = clib_host_to_net_u32 (ls_index);
17525   else
17526     {
17527       vec_add1 (ls_name, 0);
17528       strncpy ((char *) mp->ls_name, (char *) ls_name,
17529                sizeof (mp->ls_name) - 1);
17530     }
17531
17532   /* send it... */
17533   S (mp);
17534
17535   /* Use a control ping for synchronization */
17536   MPING (CONTROL_PING, mp_ping);
17537   S (mp_ping);
17538
17539   /* Wait for a reply... */
17540   W (ret);
17541   return ret;
17542 }
17543
17544 #define api_lisp_locator_dump api_one_locator_dump
17545
17546 static int
17547 api_one_locator_set_dump (vat_main_t * vam)
17548 {
17549   vl_api_one_locator_set_dump_t *mp;
17550   vl_api_control_ping_t *mp_ping;
17551   unformat_input_t *input = vam->input;
17552   u8 filter = 0;
17553   int ret;
17554
17555   /* Parse args required to build the message */
17556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17557     {
17558       if (unformat (input, "local"))
17559         {
17560           filter = 1;
17561         }
17562       else if (unformat (input, "remote"))
17563         {
17564           filter = 2;
17565         }
17566       else
17567         {
17568           errmsg ("parse error '%U'", format_unformat_error, input);
17569           return -99;
17570         }
17571     }
17572
17573   if (!vam->json_output)
17574     {
17575       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17576     }
17577
17578   M (ONE_LOCATOR_SET_DUMP, mp);
17579
17580   mp->filter = filter;
17581
17582   /* send it... */
17583   S (mp);
17584
17585   /* Use a control ping for synchronization */
17586   MPING (CONTROL_PING, mp_ping);
17587   S (mp_ping);
17588
17589   /* Wait for a reply... */
17590   W (ret);
17591   return ret;
17592 }
17593
17594 #define api_lisp_locator_set_dump api_one_locator_set_dump
17595
17596 static int
17597 api_one_eid_table_map_dump (vat_main_t * vam)
17598 {
17599   u8 is_l2 = 0;
17600   u8 mode_set = 0;
17601   unformat_input_t *input = vam->input;
17602   vl_api_one_eid_table_map_dump_t *mp;
17603   vl_api_control_ping_t *mp_ping;
17604   int ret;
17605
17606   /* Parse args required to build the message */
17607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17608     {
17609       if (unformat (input, "l2"))
17610         {
17611           is_l2 = 1;
17612           mode_set = 1;
17613         }
17614       else if (unformat (input, "l3"))
17615         {
17616           is_l2 = 0;
17617           mode_set = 1;
17618         }
17619       else
17620         {
17621           errmsg ("parse error '%U'", format_unformat_error, input);
17622           return -99;
17623         }
17624     }
17625
17626   if (!mode_set)
17627     {
17628       errmsg ("expected one of 'l2' or 'l3' parameter!");
17629       return -99;
17630     }
17631
17632   if (!vam->json_output)
17633     {
17634       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17635     }
17636
17637   M (ONE_EID_TABLE_MAP_DUMP, mp);
17638   mp->is_l2 = is_l2;
17639
17640   /* send it... */
17641   S (mp);
17642
17643   /* Use a control ping for synchronization */
17644   MPING (CONTROL_PING, mp_ping);
17645   S (mp_ping);
17646
17647   /* Wait for a reply... */
17648   W (ret);
17649   return ret;
17650 }
17651
17652 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17653
17654 static int
17655 api_one_eid_table_vni_dump (vat_main_t * vam)
17656 {
17657   vl_api_one_eid_table_vni_dump_t *mp;
17658   vl_api_control_ping_t *mp_ping;
17659   int ret;
17660
17661   if (!vam->json_output)
17662     {
17663       print (vam->ofp, "VNI");
17664     }
17665
17666   M (ONE_EID_TABLE_VNI_DUMP, mp);
17667
17668   /* send it... */
17669   S (mp);
17670
17671   /* Use a control ping for synchronization */
17672   MPING (CONTROL_PING, mp_ping);
17673   S (mp_ping);
17674
17675   /* Wait for a reply... */
17676   W (ret);
17677   return ret;
17678 }
17679
17680 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17681
17682 static int
17683 api_one_eid_table_dump (vat_main_t * vam)
17684 {
17685   unformat_input_t *i = vam->input;
17686   vl_api_one_eid_table_dump_t *mp;
17687   vl_api_control_ping_t *mp_ping;
17688   struct in_addr ip4;
17689   struct in6_addr ip6;
17690   u8 mac[6];
17691   u8 eid_type = ~0, eid_set = 0;
17692   u32 prefix_length = ~0, t, vni = 0;
17693   u8 filter = 0;
17694   int ret;
17695   lisp_nsh_api_t nsh;
17696
17697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17698     {
17699       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17700         {
17701           eid_set = 1;
17702           eid_type = 0;
17703           prefix_length = t;
17704         }
17705       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17706         {
17707           eid_set = 1;
17708           eid_type = 1;
17709           prefix_length = t;
17710         }
17711       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17712         {
17713           eid_set = 1;
17714           eid_type = 2;
17715         }
17716       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17717         {
17718           eid_set = 1;
17719           eid_type = 3;
17720         }
17721       else if (unformat (i, "vni %d", &t))
17722         {
17723           vni = t;
17724         }
17725       else if (unformat (i, "local"))
17726         {
17727           filter = 1;
17728         }
17729       else if (unformat (i, "remote"))
17730         {
17731           filter = 2;
17732         }
17733       else
17734         {
17735           errmsg ("parse error '%U'", format_unformat_error, i);
17736           return -99;
17737         }
17738     }
17739
17740   if (!vam->json_output)
17741     {
17742       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17743              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17744     }
17745
17746   M (ONE_EID_TABLE_DUMP, mp);
17747
17748   mp->filter = filter;
17749   if (eid_set)
17750     {
17751       mp->eid_set = 1;
17752       mp->vni = htonl (vni);
17753       mp->eid_type = eid_type;
17754       switch (eid_type)
17755         {
17756         case 0:
17757           mp->prefix_length = prefix_length;
17758           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17759           break;
17760         case 1:
17761           mp->prefix_length = prefix_length;
17762           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17763           break;
17764         case 2:
17765           clib_memcpy (mp->eid, mac, sizeof (mac));
17766           break;
17767         case 3:
17768           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17769           break;
17770         default:
17771           errmsg ("unknown EID type %d!", eid_type);
17772           return -99;
17773         }
17774     }
17775
17776   /* send it... */
17777   S (mp);
17778
17779   /* Use a control ping for synchronization */
17780   MPING (CONTROL_PING, mp_ping);
17781   S (mp_ping);
17782
17783   /* Wait for a reply... */
17784   W (ret);
17785   return ret;
17786 }
17787
17788 #define api_lisp_eid_table_dump api_one_eid_table_dump
17789
17790 static int
17791 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17792 {
17793   unformat_input_t *i = vam->input;
17794   vl_api_gpe_fwd_entries_get_t *mp;
17795   u8 vni_set = 0;
17796   u32 vni = ~0;
17797   int ret;
17798
17799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17800     {
17801       if (unformat (i, "vni %d", &vni))
17802         {
17803           vni_set = 1;
17804         }
17805       else
17806         {
17807           errmsg ("parse error '%U'", format_unformat_error, i);
17808           return -99;
17809         }
17810     }
17811
17812   if (!vni_set)
17813     {
17814       errmsg ("vni not set!");
17815       return -99;
17816     }
17817
17818   if (!vam->json_output)
17819     {
17820       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17821              "leid", "reid");
17822     }
17823
17824   M (GPE_FWD_ENTRIES_GET, mp);
17825   mp->vni = clib_host_to_net_u32 (vni);
17826
17827   /* send it... */
17828   S (mp);
17829
17830   /* Wait for a reply... */
17831   W (ret);
17832   return ret;
17833 }
17834
17835 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17836 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17837 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17838 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17839 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17840 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17841 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17842 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17843
17844 static int
17845 api_one_adjacencies_get (vat_main_t * vam)
17846 {
17847   unformat_input_t *i = vam->input;
17848   vl_api_one_adjacencies_get_t *mp;
17849   u8 vni_set = 0;
17850   u32 vni = ~0;
17851   int ret;
17852
17853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (i, "vni %d", &vni))
17856         {
17857           vni_set = 1;
17858         }
17859       else
17860         {
17861           errmsg ("parse error '%U'", format_unformat_error, i);
17862           return -99;
17863         }
17864     }
17865
17866   if (!vni_set)
17867     {
17868       errmsg ("vni not set!");
17869       return -99;
17870     }
17871
17872   if (!vam->json_output)
17873     {
17874       print (vam->ofp, "%s %40s", "leid", "reid");
17875     }
17876
17877   M (ONE_ADJACENCIES_GET, mp);
17878   mp->vni = clib_host_to_net_u32 (vni);
17879
17880   /* send it... */
17881   S (mp);
17882
17883   /* Wait for a reply... */
17884   W (ret);
17885   return ret;
17886 }
17887
17888 #define api_lisp_adjacencies_get api_one_adjacencies_get
17889
17890 static int
17891 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17892 {
17893   unformat_input_t *i = vam->input;
17894   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17895   int ret;
17896   u8 ip_family_set = 0, is_ip4 = 1;
17897
17898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (i, "ip4"))
17901         {
17902           ip_family_set = 1;
17903           is_ip4 = 1;
17904         }
17905       else if (unformat (i, "ip6"))
17906         {
17907           ip_family_set = 1;
17908           is_ip4 = 0;
17909         }
17910       else
17911         {
17912           errmsg ("parse error '%U'", format_unformat_error, i);
17913           return -99;
17914         }
17915     }
17916
17917   if (!ip_family_set)
17918     {
17919       errmsg ("ip family not set!");
17920       return -99;
17921     }
17922
17923   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17924   mp->is_ip4 = is_ip4;
17925
17926   /* send it... */
17927   S (mp);
17928
17929   /* Wait for a reply... */
17930   W (ret);
17931   return ret;
17932 }
17933
17934 static int
17935 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17936 {
17937   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17938   int ret;
17939
17940   if (!vam->json_output)
17941     {
17942       print (vam->ofp, "VNIs");
17943     }
17944
17945   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17946
17947   /* send it... */
17948   S (mp);
17949
17950   /* Wait for a reply... */
17951   W (ret);
17952   return ret;
17953 }
17954
17955 static int
17956 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17957 {
17958   unformat_input_t *i = vam->input;
17959   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17960   int ret = 0;
17961   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17962   struct in_addr ip4;
17963   struct in6_addr ip6;
17964   u32 table_id = 0, nh_sw_if_index = ~0;
17965
17966   clib_memset (&ip4, 0, sizeof (ip4));
17967   clib_memset (&ip6, 0, sizeof (ip6));
17968
17969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17970     {
17971       if (unformat (i, "del"))
17972         is_add = 0;
17973       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17974                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17975         {
17976           ip_set = 1;
17977           is_ip4 = 1;
17978         }
17979       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17980                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17981         {
17982           ip_set = 1;
17983           is_ip4 = 0;
17984         }
17985       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17986         {
17987           ip_set = 1;
17988           is_ip4 = 1;
17989           nh_sw_if_index = ~0;
17990         }
17991       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17992         {
17993           ip_set = 1;
17994           is_ip4 = 0;
17995           nh_sw_if_index = ~0;
17996         }
17997       else if (unformat (i, "table %d", &table_id))
17998         ;
17999       else
18000         {
18001           errmsg ("parse error '%U'", format_unformat_error, i);
18002           return -99;
18003         }
18004     }
18005
18006   if (!ip_set)
18007     {
18008       errmsg ("nh addr not set!");
18009       return -99;
18010     }
18011
18012   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18013   mp->is_add = is_add;
18014   mp->table_id = clib_host_to_net_u32 (table_id);
18015   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18016   mp->is_ip4 = is_ip4;
18017   if (is_ip4)
18018     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18019   else
18020     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18021
18022   /* send it... */
18023   S (mp);
18024
18025   /* Wait for a reply... */
18026   W (ret);
18027   return ret;
18028 }
18029
18030 static int
18031 api_one_map_server_dump (vat_main_t * vam)
18032 {
18033   vl_api_one_map_server_dump_t *mp;
18034   vl_api_control_ping_t *mp_ping;
18035   int ret;
18036
18037   if (!vam->json_output)
18038     {
18039       print (vam->ofp, "%=20s", "Map server");
18040     }
18041
18042   M (ONE_MAP_SERVER_DUMP, mp);
18043   /* send it... */
18044   S (mp);
18045
18046   /* Use a control ping for synchronization */
18047   MPING (CONTROL_PING, mp_ping);
18048   S (mp_ping);
18049
18050   /* Wait for a reply... */
18051   W (ret);
18052   return ret;
18053 }
18054
18055 #define api_lisp_map_server_dump api_one_map_server_dump
18056
18057 static int
18058 api_one_map_resolver_dump (vat_main_t * vam)
18059 {
18060   vl_api_one_map_resolver_dump_t *mp;
18061   vl_api_control_ping_t *mp_ping;
18062   int ret;
18063
18064   if (!vam->json_output)
18065     {
18066       print (vam->ofp, "%=20s", "Map resolver");
18067     }
18068
18069   M (ONE_MAP_RESOLVER_DUMP, mp);
18070   /* send it... */
18071   S (mp);
18072
18073   /* Use a control ping for synchronization */
18074   MPING (CONTROL_PING, mp_ping);
18075   S (mp_ping);
18076
18077   /* Wait for a reply... */
18078   W (ret);
18079   return ret;
18080 }
18081
18082 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18083
18084 static int
18085 api_one_stats_flush (vat_main_t * vam)
18086 {
18087   vl_api_one_stats_flush_t *mp;
18088   int ret = 0;
18089
18090   M (ONE_STATS_FLUSH, mp);
18091   S (mp);
18092   W (ret);
18093   return ret;
18094 }
18095
18096 static int
18097 api_one_stats_dump (vat_main_t * vam)
18098 {
18099   vl_api_one_stats_dump_t *mp;
18100   vl_api_control_ping_t *mp_ping;
18101   int ret;
18102
18103   M (ONE_STATS_DUMP, mp);
18104   /* send it... */
18105   S (mp);
18106
18107   /* Use a control ping for synchronization */
18108   MPING (CONTROL_PING, mp_ping);
18109   S (mp_ping);
18110
18111   /* Wait for a reply... */
18112   W (ret);
18113   return ret;
18114 }
18115
18116 static int
18117 api_show_one_status (vat_main_t * vam)
18118 {
18119   vl_api_show_one_status_t *mp;
18120   int ret;
18121
18122   if (!vam->json_output)
18123     {
18124       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18125     }
18126
18127   M (SHOW_ONE_STATUS, mp);
18128   /* send it... */
18129   S (mp);
18130   /* Wait for a reply... */
18131   W (ret);
18132   return ret;
18133 }
18134
18135 #define api_show_lisp_status api_show_one_status
18136
18137 static int
18138 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18139 {
18140   vl_api_gpe_fwd_entry_path_dump_t *mp;
18141   vl_api_control_ping_t *mp_ping;
18142   unformat_input_t *i = vam->input;
18143   u32 fwd_entry_index = ~0;
18144   int ret;
18145
18146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18147     {
18148       if (unformat (i, "index %d", &fwd_entry_index))
18149         ;
18150       else
18151         break;
18152     }
18153
18154   if (~0 == fwd_entry_index)
18155     {
18156       errmsg ("no index specified!");
18157       return -99;
18158     }
18159
18160   if (!vam->json_output)
18161     {
18162       print (vam->ofp, "first line");
18163     }
18164
18165   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18166
18167   /* send it... */
18168   S (mp);
18169   /* Use a control ping for synchronization */
18170   MPING (CONTROL_PING, mp_ping);
18171   S (mp_ping);
18172
18173   /* Wait for a reply... */
18174   W (ret);
18175   return ret;
18176 }
18177
18178 static int
18179 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18180 {
18181   vl_api_one_get_map_request_itr_rlocs_t *mp;
18182   int ret;
18183
18184   if (!vam->json_output)
18185     {
18186       print (vam->ofp, "%=20s", "itr-rlocs:");
18187     }
18188
18189   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18190   /* send it... */
18191   S (mp);
18192   /* Wait for a reply... */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18198
18199 static int
18200 api_af_packet_create (vat_main_t * vam)
18201 {
18202   unformat_input_t *i = vam->input;
18203   vl_api_af_packet_create_t *mp;
18204   u8 *host_if_name = 0;
18205   u8 hw_addr[6];
18206   u8 random_hw_addr = 1;
18207   int ret;
18208
18209   clib_memset (hw_addr, 0, sizeof (hw_addr));
18210
18211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18212     {
18213       if (unformat (i, "name %s", &host_if_name))
18214         vec_add1 (host_if_name, 0);
18215       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18216         random_hw_addr = 0;
18217       else
18218         break;
18219     }
18220
18221   if (!vec_len (host_if_name))
18222     {
18223       errmsg ("host-interface name must be specified");
18224       return -99;
18225     }
18226
18227   if (vec_len (host_if_name) > 64)
18228     {
18229       errmsg ("host-interface name too long");
18230       return -99;
18231     }
18232
18233   M (AF_PACKET_CREATE, mp);
18234
18235   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18236   clib_memcpy (mp->hw_addr, hw_addr, 6);
18237   mp->use_random_hw_addr = random_hw_addr;
18238   vec_free (host_if_name);
18239
18240   S (mp);
18241
18242   /* *INDENT-OFF* */
18243   W2 (ret,
18244       ({
18245         if (ret == 0)
18246           fprintf (vam->ofp ? vam->ofp : stderr,
18247                    " new sw_if_index = %d\n", vam->sw_if_index);
18248       }));
18249   /* *INDENT-ON* */
18250   return ret;
18251 }
18252
18253 static int
18254 api_af_packet_delete (vat_main_t * vam)
18255 {
18256   unformat_input_t *i = vam->input;
18257   vl_api_af_packet_delete_t *mp;
18258   u8 *host_if_name = 0;
18259   int ret;
18260
18261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18262     {
18263       if (unformat (i, "name %s", &host_if_name))
18264         vec_add1 (host_if_name, 0);
18265       else
18266         break;
18267     }
18268
18269   if (!vec_len (host_if_name))
18270     {
18271       errmsg ("host-interface name must be specified");
18272       return -99;
18273     }
18274
18275   if (vec_len (host_if_name) > 64)
18276     {
18277       errmsg ("host-interface name too long");
18278       return -99;
18279     }
18280
18281   M (AF_PACKET_DELETE, mp);
18282
18283   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18284   vec_free (host_if_name);
18285
18286   S (mp);
18287   W (ret);
18288   return ret;
18289 }
18290
18291 static void vl_api_af_packet_details_t_handler
18292   (vl_api_af_packet_details_t * mp)
18293 {
18294   vat_main_t *vam = &vat_main;
18295
18296   print (vam->ofp, "%-16s %d",
18297          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18298 }
18299
18300 static void vl_api_af_packet_details_t_handler_json
18301   (vl_api_af_packet_details_t * mp)
18302 {
18303   vat_main_t *vam = &vat_main;
18304   vat_json_node_t *node = NULL;
18305
18306   if (VAT_JSON_ARRAY != vam->json_tree.type)
18307     {
18308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18309       vat_json_init_array (&vam->json_tree);
18310     }
18311   node = vat_json_array_add (&vam->json_tree);
18312
18313   vat_json_init_object (node);
18314   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18315   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18316 }
18317
18318 static int
18319 api_af_packet_dump (vat_main_t * vam)
18320 {
18321   vl_api_af_packet_dump_t *mp;
18322   vl_api_control_ping_t *mp_ping;
18323   int ret;
18324
18325   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18326   /* Get list of tap interfaces */
18327   M (AF_PACKET_DUMP, mp);
18328   S (mp);
18329
18330   /* Use a control ping for synchronization */
18331   MPING (CONTROL_PING, mp_ping);
18332   S (mp_ping);
18333
18334   W (ret);
18335   return ret;
18336 }
18337
18338 static int
18339 api_policer_add_del (vat_main_t * vam)
18340 {
18341   unformat_input_t *i = vam->input;
18342   vl_api_policer_add_del_t *mp;
18343   u8 is_add = 1;
18344   u8 *name = 0;
18345   u32 cir = 0;
18346   u32 eir = 0;
18347   u64 cb = 0;
18348   u64 eb = 0;
18349   u8 rate_type = 0;
18350   u8 round_type = 0;
18351   u8 type = 0;
18352   u8 color_aware = 0;
18353   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18354   int ret;
18355
18356   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18357   conform_action.dscp = 0;
18358   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18359   exceed_action.dscp = 0;
18360   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18361   violate_action.dscp = 0;
18362
18363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18364     {
18365       if (unformat (i, "del"))
18366         is_add = 0;
18367       else if (unformat (i, "name %s", &name))
18368         vec_add1 (name, 0);
18369       else if (unformat (i, "cir %u", &cir))
18370         ;
18371       else if (unformat (i, "eir %u", &eir))
18372         ;
18373       else if (unformat (i, "cb %u", &cb))
18374         ;
18375       else if (unformat (i, "eb %u", &eb))
18376         ;
18377       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18378                          &rate_type))
18379         ;
18380       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18381                          &round_type))
18382         ;
18383       else if (unformat (i, "type %U", unformat_policer_type, &type))
18384         ;
18385       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18386                          &conform_action))
18387         ;
18388       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18389                          &exceed_action))
18390         ;
18391       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18392                          &violate_action))
18393         ;
18394       else if (unformat (i, "color-aware"))
18395         color_aware = 1;
18396       else
18397         break;
18398     }
18399
18400   if (!vec_len (name))
18401     {
18402       errmsg ("policer name must be specified");
18403       return -99;
18404     }
18405
18406   if (vec_len (name) > 64)
18407     {
18408       errmsg ("policer name too long");
18409       return -99;
18410     }
18411
18412   M (POLICER_ADD_DEL, mp);
18413
18414   clib_memcpy (mp->name, name, vec_len (name));
18415   vec_free (name);
18416   mp->is_add = is_add;
18417   mp->cir = ntohl (cir);
18418   mp->eir = ntohl (eir);
18419   mp->cb = clib_net_to_host_u64 (cb);
18420   mp->eb = clib_net_to_host_u64 (eb);
18421   mp->rate_type = rate_type;
18422   mp->round_type = round_type;
18423   mp->type = type;
18424   mp->conform_action_type = conform_action.action_type;
18425   mp->conform_dscp = conform_action.dscp;
18426   mp->exceed_action_type = exceed_action.action_type;
18427   mp->exceed_dscp = exceed_action.dscp;
18428   mp->violate_action_type = violate_action.action_type;
18429   mp->violate_dscp = violate_action.dscp;
18430   mp->color_aware = color_aware;
18431
18432   S (mp);
18433   W (ret);
18434   return ret;
18435 }
18436
18437 static int
18438 api_policer_dump (vat_main_t * vam)
18439 {
18440   unformat_input_t *i = vam->input;
18441   vl_api_policer_dump_t *mp;
18442   vl_api_control_ping_t *mp_ping;
18443   u8 *match_name = 0;
18444   u8 match_name_valid = 0;
18445   int ret;
18446
18447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18448     {
18449       if (unformat (i, "name %s", &match_name))
18450         {
18451           vec_add1 (match_name, 0);
18452           match_name_valid = 1;
18453         }
18454       else
18455         break;
18456     }
18457
18458   M (POLICER_DUMP, mp);
18459   mp->match_name_valid = match_name_valid;
18460   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18461   vec_free (match_name);
18462   /* send it... */
18463   S (mp);
18464
18465   /* Use a control ping for synchronization */
18466   MPING (CONTROL_PING, mp_ping);
18467   S (mp_ping);
18468
18469   /* Wait for a reply... */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 static int
18475 api_policer_classify_set_interface (vat_main_t * vam)
18476 {
18477   unformat_input_t *i = vam->input;
18478   vl_api_policer_classify_set_interface_t *mp;
18479   u32 sw_if_index;
18480   int sw_if_index_set;
18481   u32 ip4_table_index = ~0;
18482   u32 ip6_table_index = ~0;
18483   u32 l2_table_index = ~0;
18484   u8 is_add = 1;
18485   int ret;
18486
18487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18488     {
18489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18490         sw_if_index_set = 1;
18491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18492         sw_if_index_set = 1;
18493       else if (unformat (i, "del"))
18494         is_add = 0;
18495       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18496         ;
18497       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18498         ;
18499       else if (unformat (i, "l2-table %d", &l2_table_index))
18500         ;
18501       else
18502         {
18503           clib_warning ("parse error '%U'", format_unformat_error, i);
18504           return -99;
18505         }
18506     }
18507
18508   if (sw_if_index_set == 0)
18509     {
18510       errmsg ("missing interface name or sw_if_index");
18511       return -99;
18512     }
18513
18514   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18515
18516   mp->sw_if_index = ntohl (sw_if_index);
18517   mp->ip4_table_index = ntohl (ip4_table_index);
18518   mp->ip6_table_index = ntohl (ip6_table_index);
18519   mp->l2_table_index = ntohl (l2_table_index);
18520   mp->is_add = is_add;
18521
18522   S (mp);
18523   W (ret);
18524   return ret;
18525 }
18526
18527 static int
18528 api_policer_classify_dump (vat_main_t * vam)
18529 {
18530   unformat_input_t *i = vam->input;
18531   vl_api_policer_classify_dump_t *mp;
18532   vl_api_control_ping_t *mp_ping;
18533   u8 type = POLICER_CLASSIFY_N_TABLES;
18534   int ret;
18535
18536   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18537     ;
18538   else
18539     {
18540       errmsg ("classify table type must be specified");
18541       return -99;
18542     }
18543
18544   if (!vam->json_output)
18545     {
18546       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18547     }
18548
18549   M (POLICER_CLASSIFY_DUMP, mp);
18550   mp->type = type;
18551   /* send it... */
18552   S (mp);
18553
18554   /* Use a control ping for synchronization */
18555   MPING (CONTROL_PING, mp_ping);
18556   S (mp_ping);
18557
18558   /* Wait for a reply... */
18559   W (ret);
18560   return ret;
18561 }
18562
18563 static int
18564 api_netmap_create (vat_main_t * vam)
18565 {
18566   unformat_input_t *i = vam->input;
18567   vl_api_netmap_create_t *mp;
18568   u8 *if_name = 0;
18569   u8 hw_addr[6];
18570   u8 random_hw_addr = 1;
18571   u8 is_pipe = 0;
18572   u8 is_master = 0;
18573   int ret;
18574
18575   clib_memset (hw_addr, 0, sizeof (hw_addr));
18576
18577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18578     {
18579       if (unformat (i, "name %s", &if_name))
18580         vec_add1 (if_name, 0);
18581       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18582         random_hw_addr = 0;
18583       else if (unformat (i, "pipe"))
18584         is_pipe = 1;
18585       else if (unformat (i, "master"))
18586         is_master = 1;
18587       else if (unformat (i, "slave"))
18588         is_master = 0;
18589       else
18590         break;
18591     }
18592
18593   if (!vec_len (if_name))
18594     {
18595       errmsg ("interface name must be specified");
18596       return -99;
18597     }
18598
18599   if (vec_len (if_name) > 64)
18600     {
18601       errmsg ("interface name too long");
18602       return -99;
18603     }
18604
18605   M (NETMAP_CREATE, mp);
18606
18607   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18608   clib_memcpy (mp->hw_addr, hw_addr, 6);
18609   mp->use_random_hw_addr = random_hw_addr;
18610   mp->is_pipe = is_pipe;
18611   mp->is_master = is_master;
18612   vec_free (if_name);
18613
18614   S (mp);
18615   W (ret);
18616   return ret;
18617 }
18618
18619 static int
18620 api_netmap_delete (vat_main_t * vam)
18621 {
18622   unformat_input_t *i = vam->input;
18623   vl_api_netmap_delete_t *mp;
18624   u8 *if_name = 0;
18625   int ret;
18626
18627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18628     {
18629       if (unformat (i, "name %s", &if_name))
18630         vec_add1 (if_name, 0);
18631       else
18632         break;
18633     }
18634
18635   if (!vec_len (if_name))
18636     {
18637       errmsg ("interface name must be specified");
18638       return -99;
18639     }
18640
18641   if (vec_len (if_name) > 64)
18642     {
18643       errmsg ("interface name too long");
18644       return -99;
18645     }
18646
18647   M (NETMAP_DELETE, mp);
18648
18649   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18650   vec_free (if_name);
18651
18652   S (mp);
18653   W (ret);
18654   return ret;
18655 }
18656
18657 static u8 *
18658 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18659 {
18660   vl_api_fib_path_nh_proto_t proto =
18661     va_arg (*args, vl_api_fib_path_nh_proto_t);
18662
18663   switch (proto)
18664     {
18665     case FIB_API_PATH_NH_PROTO_IP4:
18666       s = format (s, "ip4");
18667       break;
18668     case FIB_API_PATH_NH_PROTO_IP6:
18669       s = format (s, "ip6");
18670       break;
18671     case FIB_API_PATH_NH_PROTO_MPLS:
18672       s = format (s, "mpls");
18673       break;
18674     case FIB_API_PATH_NH_PROTO_BIER:
18675       s = format (s, "bier");
18676       break;
18677     case FIB_API_PATH_NH_PROTO_ETHERNET:
18678       s = format (s, "ethernet");
18679       break;
18680     }
18681
18682   return (s);
18683 }
18684
18685 static u8 *
18686 format_vl_api_ip_address_union (u8 * s, va_list * args)
18687 {
18688   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18689   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18690
18691   switch (af)
18692     {
18693     case ADDRESS_IP4:
18694       s = format (s, "%U", format_ip4_address, u->ip4);
18695       break;
18696     case ADDRESS_IP6:
18697       s = format (s, "%U", format_ip6_address, u->ip6);
18698       break;
18699     }
18700   return (s);
18701 }
18702
18703 static u8 *
18704 format_vl_api_fib_path_type (u8 * s, va_list * args)
18705 {
18706   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18707
18708   switch (t)
18709     {
18710     case FIB_API_PATH_TYPE_NORMAL:
18711       s = format (s, "normal");
18712       break;
18713     case FIB_API_PATH_TYPE_LOCAL:
18714       s = format (s, "local");
18715       break;
18716     case FIB_API_PATH_TYPE_DROP:
18717       s = format (s, "drop");
18718       break;
18719     case FIB_API_PATH_TYPE_UDP_ENCAP:
18720       s = format (s, "udp-encap");
18721       break;
18722     case FIB_API_PATH_TYPE_BIER_IMP:
18723       s = format (s, "bier-imp");
18724       break;
18725     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18726       s = format (s, "unreach");
18727       break;
18728     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18729       s = format (s, "prohibit");
18730       break;
18731     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18732       s = format (s, "src-lookup");
18733       break;
18734     case FIB_API_PATH_TYPE_DVR:
18735       s = format (s, "dvr");
18736       break;
18737     case FIB_API_PATH_TYPE_INTERFACE_RX:
18738       s = format (s, "interface-rx");
18739       break;
18740     case FIB_API_PATH_TYPE_CLASSIFY:
18741       s = format (s, "classify");
18742       break;
18743     }
18744
18745   return (s);
18746 }
18747
18748 static void
18749 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18750 {
18751   print (vam->ofp,
18752          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18753          ntohl (fp->weight), ntohl (fp->sw_if_index),
18754          format_vl_api_fib_path_type, fp->type,
18755          format_fib_api_path_nh_proto, fp->proto,
18756          format_vl_api_ip_address_union, &fp->nh.address);
18757 }
18758
18759 static void
18760 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18761                                  vl_api_fib_path_t * fp)
18762 {
18763   struct in_addr ip4;
18764   struct in6_addr ip6;
18765
18766   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18767   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18768   vat_json_object_add_uint (node, "type", fp->type);
18769   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18770   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18771     {
18772       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18773       vat_json_object_add_ip4 (node, "next_hop", ip4);
18774     }
18775   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18776     {
18777       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18778       vat_json_object_add_ip6 (node, "next_hop", ip6);
18779     }
18780 }
18781
18782 static void
18783 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18784 {
18785   vat_main_t *vam = &vat_main;
18786   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18787   vl_api_fib_path_t *fp;
18788   i32 i;
18789
18790   print (vam->ofp, "sw_if_index %d via:",
18791          ntohl (mp->mt_tunnel.mt_sw_if_index));
18792   fp = mp->mt_tunnel.mt_paths;
18793   for (i = 0; i < count; i++)
18794     {
18795       vl_api_fib_path_print (vam, fp);
18796       fp++;
18797     }
18798
18799   print (vam->ofp, "");
18800 }
18801
18802 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18803 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18804
18805 static void
18806 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18807 {
18808   vat_main_t *vam = &vat_main;
18809   vat_json_node_t *node = NULL;
18810   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18811   vl_api_fib_path_t *fp;
18812   i32 i;
18813
18814   if (VAT_JSON_ARRAY != vam->json_tree.type)
18815     {
18816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18817       vat_json_init_array (&vam->json_tree);
18818     }
18819   node = vat_json_array_add (&vam->json_tree);
18820
18821   vat_json_init_object (node);
18822   vat_json_object_add_uint (node, "sw_if_index",
18823                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18824
18825   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18826
18827   fp = mp->mt_tunnel.mt_paths;
18828   for (i = 0; i < count; i++)
18829     {
18830       vl_api_mpls_fib_path_json_print (node, fp);
18831       fp++;
18832     }
18833 }
18834
18835 static int
18836 api_mpls_tunnel_dump (vat_main_t * vam)
18837 {
18838   vl_api_mpls_tunnel_dump_t *mp;
18839   vl_api_control_ping_t *mp_ping;
18840   int ret;
18841
18842   M (MPLS_TUNNEL_DUMP, mp);
18843
18844   S (mp);
18845
18846   /* Use a control ping for synchronization */
18847   MPING (CONTROL_PING, mp_ping);
18848   S (mp_ping);
18849
18850   W (ret);
18851   return ret;
18852 }
18853
18854 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18855 #define vl_api_mpls_table_details_t_print vl_noop_handler
18856
18857
18858 static void
18859 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18860 {
18861   vat_main_t *vam = &vat_main;
18862
18863   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18864 }
18865
18866 static void vl_api_mpls_table_details_t_handler_json
18867   (vl_api_mpls_table_details_t * mp)
18868 {
18869   vat_main_t *vam = &vat_main;
18870   vat_json_node_t *node = NULL;
18871
18872   if (VAT_JSON_ARRAY != vam->json_tree.type)
18873     {
18874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18875       vat_json_init_array (&vam->json_tree);
18876     }
18877   node = vat_json_array_add (&vam->json_tree);
18878
18879   vat_json_init_object (node);
18880   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18881 }
18882
18883 static int
18884 api_mpls_table_dump (vat_main_t * vam)
18885 {
18886   vl_api_mpls_table_dump_t *mp;
18887   vl_api_control_ping_t *mp_ping;
18888   int ret;
18889
18890   M (MPLS_TABLE_DUMP, mp);
18891   S (mp);
18892
18893   /* Use a control ping for synchronization */
18894   MPING (CONTROL_PING, mp_ping);
18895   S (mp_ping);
18896
18897   W (ret);
18898   return ret;
18899 }
18900
18901 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18902 #define vl_api_mpls_route_details_t_print vl_noop_handler
18903
18904 static void
18905 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18906 {
18907   vat_main_t *vam = &vat_main;
18908   int count = ntohl (mp->mr_route.mr_n_paths);
18909   vl_api_fib_path_t *fp;
18910   int i;
18911
18912   print (vam->ofp,
18913          "table-id %d, label %u, ess_bit %u",
18914          ntohl (mp->mr_route.mr_table_id),
18915          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18916   fp = mp->mr_route.mr_paths;
18917   for (i = 0; i < count; i++)
18918     {
18919       vl_api_fib_path_print (vam, fp);
18920       fp++;
18921     }
18922 }
18923
18924 static void vl_api_mpls_route_details_t_handler_json
18925   (vl_api_mpls_route_details_t * mp)
18926 {
18927   vat_main_t *vam = &vat_main;
18928   int count = ntohl (mp->mr_route.mr_n_paths);
18929   vat_json_node_t *node = NULL;
18930   vl_api_fib_path_t *fp;
18931   int i;
18932
18933   if (VAT_JSON_ARRAY != vam->json_tree.type)
18934     {
18935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18936       vat_json_init_array (&vam->json_tree);
18937     }
18938   node = vat_json_array_add (&vam->json_tree);
18939
18940   vat_json_init_object (node);
18941   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18942   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18943   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18944   vat_json_object_add_uint (node, "path_count", count);
18945   fp = mp->mr_route.mr_paths;
18946   for (i = 0; i < count; i++)
18947     {
18948       vl_api_mpls_fib_path_json_print (node, fp);
18949       fp++;
18950     }
18951 }
18952
18953 static int
18954 api_mpls_route_dump (vat_main_t * vam)
18955 {
18956   unformat_input_t *input = vam->input;
18957   vl_api_mpls_route_dump_t *mp;
18958   vl_api_control_ping_t *mp_ping;
18959   u32 table_id;
18960   int ret;
18961
18962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18963     {
18964       if (unformat (input, "table_id %d", &table_id))
18965         ;
18966       else
18967         break;
18968     }
18969   if (table_id == ~0)
18970     {
18971       errmsg ("missing table id");
18972       return -99;
18973     }
18974
18975   M (MPLS_ROUTE_DUMP, mp);
18976
18977   mp->table.mt_table_id = ntohl (table_id);
18978   S (mp);
18979
18980   /* Use a control ping for synchronization */
18981   MPING (CONTROL_PING, mp_ping);
18982   S (mp_ping);
18983
18984   W (ret);
18985   return ret;
18986 }
18987
18988 #define vl_api_ip_table_details_t_endian vl_noop_handler
18989 #define vl_api_ip_table_details_t_print vl_noop_handler
18990
18991 static void
18992 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18993 {
18994   vat_main_t *vam = &vat_main;
18995
18996   print (vam->ofp,
18997          "%s; table-id %d, prefix %U/%d",
18998          mp->table.name, ntohl (mp->table.table_id));
18999 }
19000
19001
19002 static void vl_api_ip_table_details_t_handler_json
19003   (vl_api_ip_table_details_t * mp)
19004 {
19005   vat_main_t *vam = &vat_main;
19006   vat_json_node_t *node = NULL;
19007
19008   if (VAT_JSON_ARRAY != vam->json_tree.type)
19009     {
19010       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19011       vat_json_init_array (&vam->json_tree);
19012     }
19013   node = vat_json_array_add (&vam->json_tree);
19014
19015   vat_json_init_object (node);
19016   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19017 }
19018
19019 static int
19020 api_ip_table_dump (vat_main_t * vam)
19021 {
19022   vl_api_ip_table_dump_t *mp;
19023   vl_api_control_ping_t *mp_ping;
19024   int ret;
19025
19026   M (IP_TABLE_DUMP, mp);
19027   S (mp);
19028
19029   /* Use a control ping for synchronization */
19030   MPING (CONTROL_PING, mp_ping);
19031   S (mp_ping);
19032
19033   W (ret);
19034   return ret;
19035 }
19036
19037 static int
19038 api_ip_mtable_dump (vat_main_t * vam)
19039 {
19040   vl_api_ip_mtable_dump_t *mp;
19041   vl_api_control_ping_t *mp_ping;
19042   int ret;
19043
19044   M (IP_MTABLE_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_mroute_dump (vat_main_t * vam)
19057 {
19058   unformat_input_t *input = vam->input;
19059   vl_api_control_ping_t *mp_ping;
19060   vl_api_ip_mroute_dump_t *mp;
19061   int ret, is_ip6;
19062   u32 table_id;
19063
19064   is_ip6 = 0;
19065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19066     {
19067       if (unformat (input, "table_id %d", &table_id))
19068         ;
19069       else if (unformat (input, "ip6"))
19070         is_ip6 = 1;
19071       else if (unformat (input, "ip4"))
19072         is_ip6 = 0;
19073       else
19074         break;
19075     }
19076   if (table_id == ~0)
19077     {
19078       errmsg ("missing table id");
19079       return -99;
19080     }
19081
19082   M (IP_MROUTE_DUMP, mp);
19083   mp->table.table_id = table_id;
19084   mp->table.is_ip6 = is_ip6;
19085   S (mp);
19086
19087   /* Use a control ping for synchronization */
19088   MPING (CONTROL_PING, mp_ping);
19089   S (mp_ping);
19090
19091   W (ret);
19092   return ret;
19093 }
19094
19095 static void vl_api_ip_neighbor_details_t_handler
19096   (vl_api_ip_neighbor_details_t * mp)
19097 {
19098   vat_main_t *vam = &vat_main;
19099
19100   print (vam->ofp, "%c %U %U",
19101          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19102          format_vl_api_mac_address, &mp->neighbor.mac_address,
19103          format_vl_api_address, &mp->neighbor.ip_address);
19104 }
19105
19106 static void vl_api_ip_neighbor_details_t_handler_json
19107   (vl_api_ip_neighbor_details_t * mp)
19108 {
19109
19110   vat_main_t *vam = &vat_main;
19111   vat_json_node_t *node;
19112
19113   if (VAT_JSON_ARRAY != vam->json_tree.type)
19114     {
19115       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19116       vat_json_init_array (&vam->json_tree);
19117     }
19118   node = vat_json_array_add (&vam->json_tree);
19119
19120   vat_json_init_object (node);
19121   vat_json_object_add_string_copy
19122     (node, "flag",
19123      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19124       (u8 *) "static" : (u8 *) "dynamic"));
19125
19126   vat_json_object_add_string_copy (node, "link_layer",
19127                                    format (0, "%U", format_vl_api_mac_address,
19128                                            &mp->neighbor.mac_address));
19129   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19130 }
19131
19132 static int
19133 api_ip_neighbor_dump (vat_main_t * vam)
19134 {
19135   unformat_input_t *i = vam->input;
19136   vl_api_ip_neighbor_dump_t *mp;
19137   vl_api_control_ping_t *mp_ping;
19138   u8 is_ipv6 = 0;
19139   u32 sw_if_index = ~0;
19140   int ret;
19141
19142   /* Parse args required to build the message */
19143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19144     {
19145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19146         ;
19147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19148         ;
19149       else if (unformat (i, "ip6"))
19150         is_ipv6 = 1;
19151       else
19152         break;
19153     }
19154
19155   if (sw_if_index == ~0)
19156     {
19157       errmsg ("missing interface name or sw_if_index");
19158       return -99;
19159     }
19160
19161   M (IP_NEIGHBOR_DUMP, mp);
19162   mp->is_ipv6 = (u8) is_ipv6;
19163   mp->sw_if_index = ntohl (sw_if_index);
19164   S (mp);
19165
19166   /* Use a control ping for synchronization */
19167   MPING (CONTROL_PING, mp_ping);
19168   S (mp_ping);
19169
19170   W (ret);
19171   return ret;
19172 }
19173
19174 #define vl_api_ip_route_details_t_endian vl_noop_handler
19175 #define vl_api_ip_route_details_t_print vl_noop_handler
19176
19177 static void
19178 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19179 {
19180   vat_main_t *vam = &vat_main;
19181   u8 count = mp->route.n_paths;
19182   vl_api_fib_path_t *fp;
19183   int i;
19184
19185   print (vam->ofp,
19186          "table-id %d, prefix %U/%d",
19187          ntohl (mp->route.table_id),
19188          format_ip46_address,
19189          mp->route.prefix.address, mp->route.prefix.address_length);
19190   for (i = 0; i < count; i++)
19191     {
19192       fp = &mp->route.paths[i];
19193
19194       vl_api_fib_path_print (vam, fp);
19195       fp++;
19196     }
19197 }
19198
19199 static void vl_api_ip_route_details_t_handler_json
19200   (vl_api_ip_route_details_t * mp)
19201 {
19202   vat_main_t *vam = &vat_main;
19203   u8 count = mp->route.n_paths;
19204   vat_json_node_t *node = NULL;
19205   struct in_addr ip4;
19206   struct in6_addr ip6;
19207   vl_api_fib_path_t *fp;
19208   int i;
19209
19210   if (VAT_JSON_ARRAY != vam->json_tree.type)
19211     {
19212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19213       vat_json_init_array (&vam->json_tree);
19214     }
19215   node = vat_json_array_add (&vam->json_tree);
19216
19217   vat_json_init_object (node);
19218   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19219   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19220     {
19221       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19222       vat_json_object_add_ip6 (node, "prefix", ip6);
19223     }
19224   else
19225     {
19226       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19227       vat_json_object_add_ip4 (node, "prefix", ip4);
19228     }
19229   vat_json_object_add_uint (node, "mask_length",
19230                             mp->route.prefix.address_length);
19231   vat_json_object_add_uint (node, "path_count", count);
19232   for (i = 0; i < count; i++)
19233     {
19234       fp = &mp->route.paths[i];
19235       vl_api_mpls_fib_path_json_print (node, fp);
19236     }
19237 }
19238
19239 static int
19240 api_ip_route_dump (vat_main_t * vam)
19241 {
19242   unformat_input_t *input = vam->input;
19243   vl_api_ip_route_dump_t *mp;
19244   vl_api_control_ping_t *mp_ping;
19245   u32 table_id;
19246   u8 is_ip6;
19247   int ret;
19248
19249   is_ip6 = 0;
19250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat (input, "table_id %d", &table_id))
19253         ;
19254       else if (unformat (input, "ip6"))
19255         is_ip6 = 1;
19256       else if (unformat (input, "ip4"))
19257         is_ip6 = 0;
19258       else
19259         break;
19260     }
19261   if (table_id == ~0)
19262     {
19263       errmsg ("missing table id");
19264       return -99;
19265     }
19266
19267   M (IP_ROUTE_DUMP, mp);
19268
19269   mp->table.table_id = table_id;
19270   mp->table.is_ip6 = is_ip6;
19271
19272   S (mp);
19273
19274   /* Use a control ping for synchronization */
19275   MPING (CONTROL_PING, mp_ping);
19276   S (mp_ping);
19277
19278   W (ret);
19279   return ret;
19280 }
19281
19282 int
19283 api_classify_table_ids (vat_main_t * vam)
19284 {
19285   vl_api_classify_table_ids_t *mp;
19286   int ret;
19287
19288   /* Construct the API message */
19289   M (CLASSIFY_TABLE_IDS, mp);
19290   mp->context = 0;
19291
19292   S (mp);
19293   W (ret);
19294   return ret;
19295 }
19296
19297 int
19298 api_classify_table_by_interface (vat_main_t * vam)
19299 {
19300   unformat_input_t *input = vam->input;
19301   vl_api_classify_table_by_interface_t *mp;
19302
19303   u32 sw_if_index = ~0;
19304   int ret;
19305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19306     {
19307       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19308         ;
19309       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19310         ;
19311       else
19312         break;
19313     }
19314   if (sw_if_index == ~0)
19315     {
19316       errmsg ("missing interface name or sw_if_index");
19317       return -99;
19318     }
19319
19320   /* Construct the API message */
19321   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19322   mp->context = 0;
19323   mp->sw_if_index = ntohl (sw_if_index);
19324
19325   S (mp);
19326   W (ret);
19327   return ret;
19328 }
19329
19330 int
19331 api_classify_table_info (vat_main_t * vam)
19332 {
19333   unformat_input_t *input = vam->input;
19334   vl_api_classify_table_info_t *mp;
19335
19336   u32 table_id = ~0;
19337   int ret;
19338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19339     {
19340       if (unformat (input, "table_id %d", &table_id))
19341         ;
19342       else
19343         break;
19344     }
19345   if (table_id == ~0)
19346     {
19347       errmsg ("missing table id");
19348       return -99;
19349     }
19350
19351   /* Construct the API message */
19352   M (CLASSIFY_TABLE_INFO, mp);
19353   mp->context = 0;
19354   mp->table_id = ntohl (table_id);
19355
19356   S (mp);
19357   W (ret);
19358   return ret;
19359 }
19360
19361 int
19362 api_classify_session_dump (vat_main_t * vam)
19363 {
19364   unformat_input_t *input = vam->input;
19365   vl_api_classify_session_dump_t *mp;
19366   vl_api_control_ping_t *mp_ping;
19367
19368   u32 table_id = ~0;
19369   int ret;
19370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19371     {
19372       if (unformat (input, "table_id %d", &table_id))
19373         ;
19374       else
19375         break;
19376     }
19377   if (table_id == ~0)
19378     {
19379       errmsg ("missing table id");
19380       return -99;
19381     }
19382
19383   /* Construct the API message */
19384   M (CLASSIFY_SESSION_DUMP, mp);
19385   mp->context = 0;
19386   mp->table_id = ntohl (table_id);
19387   S (mp);
19388
19389   /* Use a control ping for synchronization */
19390   MPING (CONTROL_PING, mp_ping);
19391   S (mp_ping);
19392
19393   W (ret);
19394   return ret;
19395 }
19396
19397 static void
19398 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19399 {
19400   vat_main_t *vam = &vat_main;
19401
19402   print (vam->ofp, "collector_address %U, collector_port %d, "
19403          "src_address %U, vrf_id %d, path_mtu %u, "
19404          "template_interval %u, udp_checksum %d",
19405          format_ip4_address, mp->collector_address,
19406          ntohs (mp->collector_port),
19407          format_ip4_address, mp->src_address,
19408          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19409          ntohl (mp->template_interval), mp->udp_checksum);
19410
19411   vam->retval = 0;
19412   vam->result_ready = 1;
19413 }
19414
19415 static void
19416   vl_api_ipfix_exporter_details_t_handler_json
19417   (vl_api_ipfix_exporter_details_t * mp)
19418 {
19419   vat_main_t *vam = &vat_main;
19420   vat_json_node_t node;
19421   struct in_addr collector_address;
19422   struct in_addr src_address;
19423
19424   vat_json_init_object (&node);
19425   clib_memcpy (&collector_address, &mp->collector_address,
19426                sizeof (collector_address));
19427   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19428   vat_json_object_add_uint (&node, "collector_port",
19429                             ntohs (mp->collector_port));
19430   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19431   vat_json_object_add_ip4 (&node, "src_address", src_address);
19432   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19433   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19434   vat_json_object_add_uint (&node, "template_interval",
19435                             ntohl (mp->template_interval));
19436   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19437
19438   vat_json_print (vam->ofp, &node);
19439   vat_json_free (&node);
19440   vam->retval = 0;
19441   vam->result_ready = 1;
19442 }
19443
19444 int
19445 api_ipfix_exporter_dump (vat_main_t * vam)
19446 {
19447   vl_api_ipfix_exporter_dump_t *mp;
19448   int ret;
19449
19450   /* Construct the API message */
19451   M (IPFIX_EXPORTER_DUMP, mp);
19452   mp->context = 0;
19453
19454   S (mp);
19455   W (ret);
19456   return ret;
19457 }
19458
19459 static int
19460 api_ipfix_classify_stream_dump (vat_main_t * vam)
19461 {
19462   vl_api_ipfix_classify_stream_dump_t *mp;
19463   int ret;
19464
19465   /* Construct the API message */
19466   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19467   mp->context = 0;
19468
19469   S (mp);
19470   W (ret);
19471   return ret;
19472   /* NOTREACHED */
19473   return 0;
19474 }
19475
19476 static void
19477   vl_api_ipfix_classify_stream_details_t_handler
19478   (vl_api_ipfix_classify_stream_details_t * mp)
19479 {
19480   vat_main_t *vam = &vat_main;
19481   print (vam->ofp, "domain_id %d, src_port %d",
19482          ntohl (mp->domain_id), ntohs (mp->src_port));
19483   vam->retval = 0;
19484   vam->result_ready = 1;
19485 }
19486
19487 static void
19488   vl_api_ipfix_classify_stream_details_t_handler_json
19489   (vl_api_ipfix_classify_stream_details_t * mp)
19490 {
19491   vat_main_t *vam = &vat_main;
19492   vat_json_node_t node;
19493
19494   vat_json_init_object (&node);
19495   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19496   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19497
19498   vat_json_print (vam->ofp, &node);
19499   vat_json_free (&node);
19500   vam->retval = 0;
19501   vam->result_ready = 1;
19502 }
19503
19504 static int
19505 api_ipfix_classify_table_dump (vat_main_t * vam)
19506 {
19507   vl_api_ipfix_classify_table_dump_t *mp;
19508   vl_api_control_ping_t *mp_ping;
19509   int ret;
19510
19511   if (!vam->json_output)
19512     {
19513       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19514              "transport_protocol");
19515     }
19516
19517   /* Construct the API message */
19518   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19519
19520   /* send it... */
19521   S (mp);
19522
19523   /* Use a control ping for synchronization */
19524   MPING (CONTROL_PING, mp_ping);
19525   S (mp_ping);
19526
19527   W (ret);
19528   return ret;
19529 }
19530
19531 static void
19532   vl_api_ipfix_classify_table_details_t_handler
19533   (vl_api_ipfix_classify_table_details_t * mp)
19534 {
19535   vat_main_t *vam = &vat_main;
19536   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19537          mp->transport_protocol);
19538 }
19539
19540 static void
19541   vl_api_ipfix_classify_table_details_t_handler_json
19542   (vl_api_ipfix_classify_table_details_t * mp)
19543 {
19544   vat_json_node_t *node = NULL;
19545   vat_main_t *vam = &vat_main;
19546
19547   if (VAT_JSON_ARRAY != vam->json_tree.type)
19548     {
19549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19550       vat_json_init_array (&vam->json_tree);
19551     }
19552
19553   node = vat_json_array_add (&vam->json_tree);
19554   vat_json_init_object (node);
19555
19556   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19557   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19558   vat_json_object_add_uint (node, "transport_protocol",
19559                             mp->transport_protocol);
19560 }
19561
19562 static int
19563 api_sw_interface_span_enable_disable (vat_main_t * vam)
19564 {
19565   unformat_input_t *i = vam->input;
19566   vl_api_sw_interface_span_enable_disable_t *mp;
19567   u32 src_sw_if_index = ~0;
19568   u32 dst_sw_if_index = ~0;
19569   u8 state = 3;
19570   int ret;
19571   u8 is_l2 = 0;
19572
19573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19574     {
19575       if (unformat
19576           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19577         ;
19578       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19579         ;
19580       else
19581         if (unformat
19582             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19583         ;
19584       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19585         ;
19586       else if (unformat (i, "disable"))
19587         state = 0;
19588       else if (unformat (i, "rx"))
19589         state = 1;
19590       else if (unformat (i, "tx"))
19591         state = 2;
19592       else if (unformat (i, "both"))
19593         state = 3;
19594       else if (unformat (i, "l2"))
19595         is_l2 = 1;
19596       else
19597         break;
19598     }
19599
19600   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19601
19602   mp->sw_if_index_from = htonl (src_sw_if_index);
19603   mp->sw_if_index_to = htonl (dst_sw_if_index);
19604   mp->state = state;
19605   mp->is_l2 = is_l2;
19606
19607   S (mp);
19608   W (ret);
19609   return ret;
19610 }
19611
19612 static void
19613 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19614                                             * mp)
19615 {
19616   vat_main_t *vam = &vat_main;
19617   u8 *sw_if_from_name = 0;
19618   u8 *sw_if_to_name = 0;
19619   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19620   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19621   char *states[] = { "none", "rx", "tx", "both" };
19622   hash_pair_t *p;
19623
19624   /* *INDENT-OFF* */
19625   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19626   ({
19627     if ((u32) p->value[0] == sw_if_index_from)
19628       {
19629         sw_if_from_name = (u8 *)(p->key);
19630         if (sw_if_to_name)
19631           break;
19632       }
19633     if ((u32) p->value[0] == sw_if_index_to)
19634       {
19635         sw_if_to_name = (u8 *)(p->key);
19636         if (sw_if_from_name)
19637           break;
19638       }
19639   }));
19640   /* *INDENT-ON* */
19641   print (vam->ofp, "%20s => %20s (%s) %s",
19642          sw_if_from_name, sw_if_to_name, states[mp->state],
19643          mp->is_l2 ? "l2" : "device");
19644 }
19645
19646 static void
19647   vl_api_sw_interface_span_details_t_handler_json
19648   (vl_api_sw_interface_span_details_t * mp)
19649 {
19650   vat_main_t *vam = &vat_main;
19651   vat_json_node_t *node = NULL;
19652   u8 *sw_if_from_name = 0;
19653   u8 *sw_if_to_name = 0;
19654   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19655   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19656   hash_pair_t *p;
19657
19658   /* *INDENT-OFF* */
19659   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19660   ({
19661     if ((u32) p->value[0] == sw_if_index_from)
19662       {
19663         sw_if_from_name = (u8 *)(p->key);
19664         if (sw_if_to_name)
19665           break;
19666       }
19667     if ((u32) p->value[0] == sw_if_index_to)
19668       {
19669         sw_if_to_name = (u8 *)(p->key);
19670         if (sw_if_from_name)
19671           break;
19672       }
19673   }));
19674   /* *INDENT-ON* */
19675
19676   if (VAT_JSON_ARRAY != vam->json_tree.type)
19677     {
19678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19679       vat_json_init_array (&vam->json_tree);
19680     }
19681   node = vat_json_array_add (&vam->json_tree);
19682
19683   vat_json_init_object (node);
19684   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19685   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19686   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19687   if (0 != sw_if_to_name)
19688     {
19689       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19690     }
19691   vat_json_object_add_uint (node, "state", mp->state);
19692   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19693 }
19694
19695 static int
19696 api_sw_interface_span_dump (vat_main_t * vam)
19697 {
19698   unformat_input_t *input = vam->input;
19699   vl_api_sw_interface_span_dump_t *mp;
19700   vl_api_control_ping_t *mp_ping;
19701   u8 is_l2 = 0;
19702   int ret;
19703
19704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19705     {
19706       if (unformat (input, "l2"))
19707         is_l2 = 1;
19708       else
19709         break;
19710     }
19711
19712   M (SW_INTERFACE_SPAN_DUMP, mp);
19713   mp->is_l2 = is_l2;
19714   S (mp);
19715
19716   /* Use a control ping for synchronization */
19717   MPING (CONTROL_PING, mp_ping);
19718   S (mp_ping);
19719
19720   W (ret);
19721   return ret;
19722 }
19723
19724 int
19725 api_pg_create_interface (vat_main_t * vam)
19726 {
19727   unformat_input_t *input = vam->input;
19728   vl_api_pg_create_interface_t *mp;
19729
19730   u32 if_id = ~0;
19731   int ret;
19732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19733     {
19734       if (unformat (input, "if_id %d", &if_id))
19735         ;
19736       else
19737         break;
19738     }
19739   if (if_id == ~0)
19740     {
19741       errmsg ("missing pg interface index");
19742       return -99;
19743     }
19744
19745   /* Construct the API message */
19746   M (PG_CREATE_INTERFACE, mp);
19747   mp->context = 0;
19748   mp->interface_id = ntohl (if_id);
19749
19750   S (mp);
19751   W (ret);
19752   return ret;
19753 }
19754
19755 int
19756 api_pg_capture (vat_main_t * vam)
19757 {
19758   unformat_input_t *input = vam->input;
19759   vl_api_pg_capture_t *mp;
19760
19761   u32 if_id = ~0;
19762   u8 enable = 1;
19763   u32 count = 1;
19764   u8 pcap_file_set = 0;
19765   u8 *pcap_file = 0;
19766   int ret;
19767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19768     {
19769       if (unformat (input, "if_id %d", &if_id))
19770         ;
19771       else if (unformat (input, "pcap %s", &pcap_file))
19772         pcap_file_set = 1;
19773       else if (unformat (input, "count %d", &count))
19774         ;
19775       else if (unformat (input, "disable"))
19776         enable = 0;
19777       else
19778         break;
19779     }
19780   if (if_id == ~0)
19781     {
19782       errmsg ("missing pg interface index");
19783       return -99;
19784     }
19785   if (pcap_file_set > 0)
19786     {
19787       if (vec_len (pcap_file) > 255)
19788         {
19789           errmsg ("pcap file name is too long");
19790           return -99;
19791         }
19792     }
19793
19794   u32 name_len = vec_len (pcap_file);
19795   /* Construct the API message */
19796   M (PG_CAPTURE, mp);
19797   mp->context = 0;
19798   mp->interface_id = ntohl (if_id);
19799   mp->is_enabled = enable;
19800   mp->count = ntohl (count);
19801   mp->pcap_name_length = ntohl (name_len);
19802   if (pcap_file_set != 0)
19803     {
19804       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19805     }
19806   vec_free (pcap_file);
19807
19808   S (mp);
19809   W (ret);
19810   return ret;
19811 }
19812
19813 int
19814 api_pg_enable_disable (vat_main_t * vam)
19815 {
19816   unformat_input_t *input = vam->input;
19817   vl_api_pg_enable_disable_t *mp;
19818
19819   u8 enable = 1;
19820   u8 stream_name_set = 0;
19821   u8 *stream_name = 0;
19822   int ret;
19823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19824     {
19825       if (unformat (input, "stream %s", &stream_name))
19826         stream_name_set = 1;
19827       else if (unformat (input, "disable"))
19828         enable = 0;
19829       else
19830         break;
19831     }
19832
19833   if (stream_name_set > 0)
19834     {
19835       if (vec_len (stream_name) > 255)
19836         {
19837           errmsg ("stream name too long");
19838           return -99;
19839         }
19840     }
19841
19842   u32 name_len = vec_len (stream_name);
19843   /* Construct the API message */
19844   M (PG_ENABLE_DISABLE, mp);
19845   mp->context = 0;
19846   mp->is_enabled = enable;
19847   if (stream_name_set != 0)
19848     {
19849       mp->stream_name_length = ntohl (name_len);
19850       clib_memcpy (mp->stream_name, stream_name, name_len);
19851     }
19852   vec_free (stream_name);
19853
19854   S (mp);
19855   W (ret);
19856   return ret;
19857 }
19858
19859 int
19860 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19861 {
19862   unformat_input_t *input = vam->input;
19863   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19864
19865   u16 *low_ports = 0;
19866   u16 *high_ports = 0;
19867   u16 this_low;
19868   u16 this_hi;
19869   vl_api_prefix_t prefix;
19870   u32 tmp, tmp2;
19871   u8 prefix_set = 0;
19872   u32 vrf_id = ~0;
19873   u8 is_add = 1;
19874   int ret;
19875
19876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19877     {
19878       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19879         prefix_set = 1;
19880       else if (unformat (input, "vrf %d", &vrf_id))
19881         ;
19882       else if (unformat (input, "del"))
19883         is_add = 0;
19884       else if (unformat (input, "port %d", &tmp))
19885         {
19886           if (tmp == 0 || tmp > 65535)
19887             {
19888               errmsg ("port %d out of range", tmp);
19889               return -99;
19890             }
19891           this_low = tmp;
19892           this_hi = this_low + 1;
19893           vec_add1 (low_ports, this_low);
19894           vec_add1 (high_ports, this_hi);
19895         }
19896       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19897         {
19898           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19899             {
19900               errmsg ("incorrect range parameters");
19901               return -99;
19902             }
19903           this_low = tmp;
19904           /* Note: in debug CLI +1 is added to high before
19905              passing to real fn that does "the work"
19906              (ip_source_and_port_range_check_add_del).
19907              This fn is a wrapper around the binary API fn a
19908              control plane will call, which expects this increment
19909              to have occurred. Hence letting the binary API control
19910              plane fn do the increment for consistency between VAT
19911              and other control planes.
19912            */
19913           this_hi = tmp2;
19914           vec_add1 (low_ports, this_low);
19915           vec_add1 (high_ports, this_hi);
19916         }
19917       else
19918         break;
19919     }
19920
19921   if (prefix_set == 0)
19922     {
19923       errmsg ("<address>/<mask> not specified");
19924       return -99;
19925     }
19926
19927   if (vrf_id == ~0)
19928     {
19929       errmsg ("VRF ID required, not specified");
19930       return -99;
19931     }
19932
19933   if (vrf_id == 0)
19934     {
19935       errmsg
19936         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19937       return -99;
19938     }
19939
19940   if (vec_len (low_ports) == 0)
19941     {
19942       errmsg ("At least one port or port range required");
19943       return -99;
19944     }
19945
19946   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19947
19948   mp->is_add = is_add;
19949
19950   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19951
19952   mp->number_of_ranges = vec_len (low_ports);
19953
19954   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19955   vec_free (low_ports);
19956
19957   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19958   vec_free (high_ports);
19959
19960   mp->vrf_id = ntohl (vrf_id);
19961
19962   S (mp);
19963   W (ret);
19964   return ret;
19965 }
19966
19967 int
19968 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19969 {
19970   unformat_input_t *input = vam->input;
19971   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19972   u32 sw_if_index = ~0;
19973   int vrf_set = 0;
19974   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19975   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19976   u8 is_add = 1;
19977   int ret;
19978
19979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19980     {
19981       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19982         ;
19983       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19984         ;
19985       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19986         vrf_set = 1;
19987       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19988         vrf_set = 1;
19989       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19990         vrf_set = 1;
19991       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19992         vrf_set = 1;
19993       else if (unformat (input, "del"))
19994         is_add = 0;
19995       else
19996         break;
19997     }
19998
19999   if (sw_if_index == ~0)
20000     {
20001       errmsg ("Interface required but not specified");
20002       return -99;
20003     }
20004
20005   if (vrf_set == 0)
20006     {
20007       errmsg ("VRF ID required but not specified");
20008       return -99;
20009     }
20010
20011   if (tcp_out_vrf_id == 0
20012       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20013     {
20014       errmsg
20015         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20016       return -99;
20017     }
20018
20019   /* Construct the API message */
20020   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20021
20022   mp->sw_if_index = ntohl (sw_if_index);
20023   mp->is_add = is_add;
20024   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20025   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20026   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20027   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20028
20029   /* send it... */
20030   S (mp);
20031
20032   /* Wait for a reply... */
20033   W (ret);
20034   return ret;
20035 }
20036
20037 static int
20038 api_set_punt (vat_main_t * vam)
20039 {
20040   unformat_input_t *i = vam->input;
20041   vl_api_address_family_t af;
20042   vl_api_set_punt_t *mp;
20043   u32 protocol = ~0;
20044   u32 port = ~0;
20045   int is_add = 1;
20046   int ret;
20047
20048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20049     {
20050       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20051         ;
20052       else if (unformat (i, "protocol %d", &protocol))
20053         ;
20054       else if (unformat (i, "port %d", &port))
20055         ;
20056       else if (unformat (i, "del"))
20057         is_add = 0;
20058       else
20059         {
20060           clib_warning ("parse error '%U'", format_unformat_error, i);
20061           return -99;
20062         }
20063     }
20064
20065   M (SET_PUNT, mp);
20066
20067   mp->is_add = (u8) is_add;
20068   mp->punt.type = PUNT_API_TYPE_L4;
20069   mp->punt.punt.l4.af = af;
20070   mp->punt.punt.l4.protocol = (u8) protocol;
20071   mp->punt.punt.l4.port = htons ((u16) port);
20072
20073   S (mp);
20074   W (ret);
20075   return ret;
20076 }
20077
20078 static int
20079 api_delete_subif (vat_main_t * vam)
20080 {
20081   unformat_input_t *i = vam->input;
20082   vl_api_delete_subif_t *mp;
20083   u32 sw_if_index = ~0;
20084   int ret;
20085
20086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20087     {
20088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20089         ;
20090       if (unformat (i, "sw_if_index %d", &sw_if_index))
20091         ;
20092       else
20093         break;
20094     }
20095
20096   if (sw_if_index == ~0)
20097     {
20098       errmsg ("missing sw_if_index");
20099       return -99;
20100     }
20101
20102   /* Construct the API message */
20103   M (DELETE_SUBIF, mp);
20104   mp->sw_if_index = ntohl (sw_if_index);
20105
20106   S (mp);
20107   W (ret);
20108   return ret;
20109 }
20110
20111 #define foreach_pbb_vtr_op      \
20112 _("disable",  L2_VTR_DISABLED)  \
20113 _("pop",  L2_VTR_POP_2)         \
20114 _("push",  L2_VTR_PUSH_2)
20115
20116 static int
20117 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20118 {
20119   unformat_input_t *i = vam->input;
20120   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20121   u32 sw_if_index = ~0, vtr_op = ~0;
20122   u16 outer_tag = ~0;
20123   u8 dmac[6], smac[6];
20124   u8 dmac_set = 0, smac_set = 0;
20125   u16 vlanid = 0;
20126   u32 sid = ~0;
20127   u32 tmp;
20128   int ret;
20129
20130   /* Shut up coverity */
20131   clib_memset (dmac, 0, sizeof (dmac));
20132   clib_memset (smac, 0, sizeof (smac));
20133
20134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20135     {
20136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20137         ;
20138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20139         ;
20140       else if (unformat (i, "vtr_op %d", &vtr_op))
20141         ;
20142 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20143       foreach_pbb_vtr_op
20144 #undef _
20145         else if (unformat (i, "translate_pbb_stag"))
20146         {
20147           if (unformat (i, "%d", &tmp))
20148             {
20149               vtr_op = L2_VTR_TRANSLATE_2_1;
20150               outer_tag = tmp;
20151             }
20152           else
20153             {
20154               errmsg
20155                 ("translate_pbb_stag operation requires outer tag definition");
20156               return -99;
20157             }
20158         }
20159       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20160         dmac_set++;
20161       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20162         smac_set++;
20163       else if (unformat (i, "sid %d", &sid))
20164         ;
20165       else if (unformat (i, "vlanid %d", &tmp))
20166         vlanid = tmp;
20167       else
20168         {
20169           clib_warning ("parse error '%U'", format_unformat_error, i);
20170           return -99;
20171         }
20172     }
20173
20174   if ((sw_if_index == ~0) || (vtr_op == ~0))
20175     {
20176       errmsg ("missing sw_if_index or vtr operation");
20177       return -99;
20178     }
20179   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20180       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20181     {
20182       errmsg
20183         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20184       return -99;
20185     }
20186
20187   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20188   mp->sw_if_index = ntohl (sw_if_index);
20189   mp->vtr_op = ntohl (vtr_op);
20190   mp->outer_tag = ntohs (outer_tag);
20191   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20192   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20193   mp->b_vlanid = ntohs (vlanid);
20194   mp->i_sid = ntohl (sid);
20195
20196   S (mp);
20197   W (ret);
20198   return ret;
20199 }
20200
20201 static int
20202 api_flow_classify_set_interface (vat_main_t * vam)
20203 {
20204   unformat_input_t *i = vam->input;
20205   vl_api_flow_classify_set_interface_t *mp;
20206   u32 sw_if_index;
20207   int sw_if_index_set;
20208   u32 ip4_table_index = ~0;
20209   u32 ip6_table_index = ~0;
20210   u8 is_add = 1;
20211   int ret;
20212
20213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20214     {
20215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20216         sw_if_index_set = 1;
20217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20218         sw_if_index_set = 1;
20219       else if (unformat (i, "del"))
20220         is_add = 0;
20221       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20222         ;
20223       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20224         ;
20225       else
20226         {
20227           clib_warning ("parse error '%U'", format_unformat_error, i);
20228           return -99;
20229         }
20230     }
20231
20232   if (sw_if_index_set == 0)
20233     {
20234       errmsg ("missing interface name or sw_if_index");
20235       return -99;
20236     }
20237
20238   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20239
20240   mp->sw_if_index = ntohl (sw_if_index);
20241   mp->ip4_table_index = ntohl (ip4_table_index);
20242   mp->ip6_table_index = ntohl (ip6_table_index);
20243   mp->is_add = is_add;
20244
20245   S (mp);
20246   W (ret);
20247   return ret;
20248 }
20249
20250 static int
20251 api_flow_classify_dump (vat_main_t * vam)
20252 {
20253   unformat_input_t *i = vam->input;
20254   vl_api_flow_classify_dump_t *mp;
20255   vl_api_control_ping_t *mp_ping;
20256   u8 type = FLOW_CLASSIFY_N_TABLES;
20257   int ret;
20258
20259   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20260     ;
20261   else
20262     {
20263       errmsg ("classify table type must be specified");
20264       return -99;
20265     }
20266
20267   if (!vam->json_output)
20268     {
20269       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20270     }
20271
20272   M (FLOW_CLASSIFY_DUMP, mp);
20273   mp->type = type;
20274   /* send it... */
20275   S (mp);
20276
20277   /* Use a control ping for synchronization */
20278   MPING (CONTROL_PING, mp_ping);
20279   S (mp_ping);
20280
20281   /* Wait for a reply... */
20282   W (ret);
20283   return ret;
20284 }
20285
20286 static int
20287 api_feature_enable_disable (vat_main_t * vam)
20288 {
20289   unformat_input_t *i = vam->input;
20290   vl_api_feature_enable_disable_t *mp;
20291   u8 *arc_name = 0;
20292   u8 *feature_name = 0;
20293   u32 sw_if_index = ~0;
20294   u8 enable = 1;
20295   int ret;
20296
20297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20298     {
20299       if (unformat (i, "arc_name %s", &arc_name))
20300         ;
20301       else if (unformat (i, "feature_name %s", &feature_name))
20302         ;
20303       else
20304         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20305         ;
20306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20307         ;
20308       else if (unformat (i, "disable"))
20309         enable = 0;
20310       else
20311         break;
20312     }
20313
20314   if (arc_name == 0)
20315     {
20316       errmsg ("missing arc name");
20317       return -99;
20318     }
20319   if (vec_len (arc_name) > 63)
20320     {
20321       errmsg ("arc name too long");
20322     }
20323
20324   if (feature_name == 0)
20325     {
20326       errmsg ("missing feature name");
20327       return -99;
20328     }
20329   if (vec_len (feature_name) > 63)
20330     {
20331       errmsg ("feature name too long");
20332     }
20333
20334   if (sw_if_index == ~0)
20335     {
20336       errmsg ("missing interface name or sw_if_index");
20337       return -99;
20338     }
20339
20340   /* Construct the API message */
20341   M (FEATURE_ENABLE_DISABLE, mp);
20342   mp->sw_if_index = ntohl (sw_if_index);
20343   mp->enable = enable;
20344   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20345   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20346   vec_free (arc_name);
20347   vec_free (feature_name);
20348
20349   S (mp);
20350   W (ret);
20351   return ret;
20352 }
20353
20354 static int
20355 api_sw_interface_tag_add_del (vat_main_t * vam)
20356 {
20357   unformat_input_t *i = vam->input;
20358   vl_api_sw_interface_tag_add_del_t *mp;
20359   u32 sw_if_index = ~0;
20360   u8 *tag = 0;
20361   u8 enable = 1;
20362   int ret;
20363
20364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20365     {
20366       if (unformat (i, "tag %s", &tag))
20367         ;
20368       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20369         ;
20370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20371         ;
20372       else if (unformat (i, "del"))
20373         enable = 0;
20374       else
20375         break;
20376     }
20377
20378   if (sw_if_index == ~0)
20379     {
20380       errmsg ("missing interface name or sw_if_index");
20381       return -99;
20382     }
20383
20384   if (enable && (tag == 0))
20385     {
20386       errmsg ("no tag specified");
20387       return -99;
20388     }
20389
20390   /* Construct the API message */
20391   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20392   mp->sw_if_index = ntohl (sw_if_index);
20393   mp->is_add = enable;
20394   if (enable)
20395     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20396   vec_free (tag);
20397
20398   S (mp);
20399   W (ret);
20400   return ret;
20401 }
20402
20403 static void vl_api_l2_xconnect_details_t_handler
20404   (vl_api_l2_xconnect_details_t * mp)
20405 {
20406   vat_main_t *vam = &vat_main;
20407
20408   print (vam->ofp, "%15d%15d",
20409          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20410 }
20411
20412 static void vl_api_l2_xconnect_details_t_handler_json
20413   (vl_api_l2_xconnect_details_t * mp)
20414 {
20415   vat_main_t *vam = &vat_main;
20416   vat_json_node_t *node = NULL;
20417
20418   if (VAT_JSON_ARRAY != vam->json_tree.type)
20419     {
20420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20421       vat_json_init_array (&vam->json_tree);
20422     }
20423   node = vat_json_array_add (&vam->json_tree);
20424
20425   vat_json_init_object (node);
20426   vat_json_object_add_uint (node, "rx_sw_if_index",
20427                             ntohl (mp->rx_sw_if_index));
20428   vat_json_object_add_uint (node, "tx_sw_if_index",
20429                             ntohl (mp->tx_sw_if_index));
20430 }
20431
20432 static int
20433 api_l2_xconnect_dump (vat_main_t * vam)
20434 {
20435   vl_api_l2_xconnect_dump_t *mp;
20436   vl_api_control_ping_t *mp_ping;
20437   int ret;
20438
20439   if (!vam->json_output)
20440     {
20441       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20442     }
20443
20444   M (L2_XCONNECT_DUMP, mp);
20445
20446   S (mp);
20447
20448   /* Use a control ping for synchronization */
20449   MPING (CONTROL_PING, mp_ping);
20450   S (mp_ping);
20451
20452   W (ret);
20453   return ret;
20454 }
20455
20456 static int
20457 api_hw_interface_set_mtu (vat_main_t * vam)
20458 {
20459   unformat_input_t *i = vam->input;
20460   vl_api_hw_interface_set_mtu_t *mp;
20461   u32 sw_if_index = ~0;
20462   u32 mtu = 0;
20463   int ret;
20464
20465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20466     {
20467       if (unformat (i, "mtu %d", &mtu))
20468         ;
20469       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20470         ;
20471       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20472         ;
20473       else
20474         break;
20475     }
20476
20477   if (sw_if_index == ~0)
20478     {
20479       errmsg ("missing interface name or sw_if_index");
20480       return -99;
20481     }
20482
20483   if (mtu == 0)
20484     {
20485       errmsg ("no mtu specified");
20486       return -99;
20487     }
20488
20489   /* Construct the API message */
20490   M (HW_INTERFACE_SET_MTU, mp);
20491   mp->sw_if_index = ntohl (sw_if_index);
20492   mp->mtu = ntohs ((u16) mtu);
20493
20494   S (mp);
20495   W (ret);
20496   return ret;
20497 }
20498
20499 static int
20500 api_p2p_ethernet_add (vat_main_t * vam)
20501 {
20502   unformat_input_t *i = vam->input;
20503   vl_api_p2p_ethernet_add_t *mp;
20504   u32 parent_if_index = ~0;
20505   u32 sub_id = ~0;
20506   u8 remote_mac[6];
20507   u8 mac_set = 0;
20508   int ret;
20509
20510   clib_memset (remote_mac, 0, sizeof (remote_mac));
20511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20512     {
20513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20514         ;
20515       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20516         ;
20517       else
20518         if (unformat
20519             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20520         mac_set++;
20521       else if (unformat (i, "sub_id %d", &sub_id))
20522         ;
20523       else
20524         {
20525           clib_warning ("parse error '%U'", format_unformat_error, i);
20526           return -99;
20527         }
20528     }
20529
20530   if (parent_if_index == ~0)
20531     {
20532       errmsg ("missing interface name or sw_if_index");
20533       return -99;
20534     }
20535   if (mac_set == 0)
20536     {
20537       errmsg ("missing remote mac address");
20538       return -99;
20539     }
20540   if (sub_id == ~0)
20541     {
20542       errmsg ("missing sub-interface id");
20543       return -99;
20544     }
20545
20546   M (P2P_ETHERNET_ADD, mp);
20547   mp->parent_if_index = ntohl (parent_if_index);
20548   mp->subif_id = ntohl (sub_id);
20549   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20550
20551   S (mp);
20552   W (ret);
20553   return ret;
20554 }
20555
20556 static int
20557 api_p2p_ethernet_del (vat_main_t * vam)
20558 {
20559   unformat_input_t *i = vam->input;
20560   vl_api_p2p_ethernet_del_t *mp;
20561   u32 parent_if_index = ~0;
20562   u8 remote_mac[6];
20563   u8 mac_set = 0;
20564   int ret;
20565
20566   clib_memset (remote_mac, 0, sizeof (remote_mac));
20567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20568     {
20569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20570         ;
20571       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20572         ;
20573       else
20574         if (unformat
20575             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20576         mac_set++;
20577       else
20578         {
20579           clib_warning ("parse error '%U'", format_unformat_error, i);
20580           return -99;
20581         }
20582     }
20583
20584   if (parent_if_index == ~0)
20585     {
20586       errmsg ("missing interface name or sw_if_index");
20587       return -99;
20588     }
20589   if (mac_set == 0)
20590     {
20591       errmsg ("missing remote mac address");
20592       return -99;
20593     }
20594
20595   M (P2P_ETHERNET_DEL, mp);
20596   mp->parent_if_index = ntohl (parent_if_index);
20597   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20598
20599   S (mp);
20600   W (ret);
20601   return ret;
20602 }
20603
20604 static int
20605 api_lldp_config (vat_main_t * vam)
20606 {
20607   unformat_input_t *i = vam->input;
20608   vl_api_lldp_config_t *mp;
20609   int tx_hold = 0;
20610   int tx_interval = 0;
20611   u8 *sys_name = NULL;
20612   int ret;
20613
20614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20615     {
20616       if (unformat (i, "system-name %s", &sys_name))
20617         ;
20618       else if (unformat (i, "tx-hold %d", &tx_hold))
20619         ;
20620       else if (unformat (i, "tx-interval %d", &tx_interval))
20621         ;
20622       else
20623         {
20624           clib_warning ("parse error '%U'", format_unformat_error, i);
20625           return -99;
20626         }
20627     }
20628
20629   vec_add1 (sys_name, 0);
20630
20631   M (LLDP_CONFIG, mp);
20632   mp->tx_hold = htonl (tx_hold);
20633   mp->tx_interval = htonl (tx_interval);
20634   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20635   vec_free (sys_name);
20636
20637   S (mp);
20638   W (ret);
20639   return ret;
20640 }
20641
20642 static int
20643 api_sw_interface_set_lldp (vat_main_t * vam)
20644 {
20645   unformat_input_t *i = vam->input;
20646   vl_api_sw_interface_set_lldp_t *mp;
20647   u32 sw_if_index = ~0;
20648   u32 enable = 1;
20649   u8 *port_desc = NULL, *mgmt_oid = NULL;
20650   ip4_address_t ip4_addr;
20651   ip6_address_t ip6_addr;
20652   int ret;
20653
20654   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20655   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20656
20657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20658     {
20659       if (unformat (i, "disable"))
20660         enable = 0;
20661       else
20662         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20663         ;
20664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20665         ;
20666       else if (unformat (i, "port-desc %s", &port_desc))
20667         ;
20668       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20669         ;
20670       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20671         ;
20672       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20673         ;
20674       else
20675         break;
20676     }
20677
20678   if (sw_if_index == ~0)
20679     {
20680       errmsg ("missing interface name or sw_if_index");
20681       return -99;
20682     }
20683
20684   /* Construct the API message */
20685   vec_add1 (port_desc, 0);
20686   vec_add1 (mgmt_oid, 0);
20687   M (SW_INTERFACE_SET_LLDP, mp);
20688   mp->sw_if_index = ntohl (sw_if_index);
20689   mp->enable = enable;
20690   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20691   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20692   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20693   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20694   vec_free (port_desc);
20695   vec_free (mgmt_oid);
20696
20697   S (mp);
20698   W (ret);
20699   return ret;
20700 }
20701
20702 static int
20703 api_tcp_configure_src_addresses (vat_main_t * vam)
20704 {
20705   vl_api_tcp_configure_src_addresses_t *mp;
20706   unformat_input_t *i = vam->input;
20707   ip4_address_t v4first, v4last;
20708   ip6_address_t v6first, v6last;
20709   u8 range_set = 0;
20710   u32 vrf_id = 0;
20711   int ret;
20712
20713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20714     {
20715       if (unformat (i, "%U - %U",
20716                     unformat_ip4_address, &v4first,
20717                     unformat_ip4_address, &v4last))
20718         {
20719           if (range_set)
20720             {
20721               errmsg ("one range per message (range already set)");
20722               return -99;
20723             }
20724           range_set = 1;
20725         }
20726       else if (unformat (i, "%U - %U",
20727                          unformat_ip6_address, &v6first,
20728                          unformat_ip6_address, &v6last))
20729         {
20730           if (range_set)
20731             {
20732               errmsg ("one range per message (range already set)");
20733               return -99;
20734             }
20735           range_set = 2;
20736         }
20737       else if (unformat (i, "vrf %d", &vrf_id))
20738         ;
20739       else
20740         break;
20741     }
20742
20743   if (range_set == 0)
20744     {
20745       errmsg ("address range not set");
20746       return -99;
20747     }
20748
20749   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20750   mp->vrf_id = ntohl (vrf_id);
20751   /* ipv6? */
20752   if (range_set == 2)
20753     {
20754       mp->is_ipv6 = 1;
20755       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20756       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20757     }
20758   else
20759     {
20760       mp->is_ipv6 = 0;
20761       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20762       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20763     }
20764   S (mp);
20765   W (ret);
20766   return ret;
20767 }
20768
20769 static void vl_api_app_namespace_add_del_reply_t_handler
20770   (vl_api_app_namespace_add_del_reply_t * mp)
20771 {
20772   vat_main_t *vam = &vat_main;
20773   i32 retval = ntohl (mp->retval);
20774   if (vam->async_mode)
20775     {
20776       vam->async_errors += (retval < 0);
20777     }
20778   else
20779     {
20780       vam->retval = retval;
20781       if (retval == 0)
20782         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20783       vam->result_ready = 1;
20784     }
20785 }
20786
20787 static void vl_api_app_namespace_add_del_reply_t_handler_json
20788   (vl_api_app_namespace_add_del_reply_t * mp)
20789 {
20790   vat_main_t *vam = &vat_main;
20791   vat_json_node_t node;
20792
20793   vat_json_init_object (&node);
20794   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20795   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20796
20797   vat_json_print (vam->ofp, &node);
20798   vat_json_free (&node);
20799
20800   vam->retval = ntohl (mp->retval);
20801   vam->result_ready = 1;
20802 }
20803
20804 static int
20805 api_app_namespace_add_del (vat_main_t * vam)
20806 {
20807   vl_api_app_namespace_add_del_t *mp;
20808   unformat_input_t *i = vam->input;
20809   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20810   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20811   u64 secret;
20812   int ret;
20813
20814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20815     {
20816       if (unformat (i, "id %_%v%_", &ns_id))
20817         ;
20818       else if (unformat (i, "secret %lu", &secret))
20819         secret_set = 1;
20820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20821         sw_if_index_set = 1;
20822       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20823         ;
20824       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20825         ;
20826       else
20827         break;
20828     }
20829   if (!ns_id || !secret_set || !sw_if_index_set)
20830     {
20831       errmsg ("namespace id, secret and sw_if_index must be set");
20832       return -99;
20833     }
20834   if (vec_len (ns_id) > 64)
20835     {
20836       errmsg ("namespace id too long");
20837       return -99;
20838     }
20839   M (APP_NAMESPACE_ADD_DEL, mp);
20840
20841   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20842   mp->namespace_id_len = vec_len (ns_id);
20843   mp->secret = clib_host_to_net_u64 (secret);
20844   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20845   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20846   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20847   vec_free (ns_id);
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static int
20854 api_sock_init_shm (vat_main_t * vam)
20855 {
20856 #if VPP_API_TEST_BUILTIN == 0
20857   unformat_input_t *i = vam->input;
20858   vl_api_shm_elem_config_t *config = 0;
20859   u64 size = 64 << 20;
20860   int rv;
20861
20862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20863     {
20864       if (unformat (i, "size %U", unformat_memory_size, &size))
20865         ;
20866       else
20867         break;
20868     }
20869
20870   /*
20871    * Canned custom ring allocator config.
20872    * Should probably parse all of this
20873    */
20874   vec_validate (config, 6);
20875   config[0].type = VL_API_VLIB_RING;
20876   config[0].size = 256;
20877   config[0].count = 32;
20878
20879   config[1].type = VL_API_VLIB_RING;
20880   config[1].size = 1024;
20881   config[1].count = 16;
20882
20883   config[2].type = VL_API_VLIB_RING;
20884   config[2].size = 4096;
20885   config[2].count = 2;
20886
20887   config[3].type = VL_API_CLIENT_RING;
20888   config[3].size = 256;
20889   config[3].count = 32;
20890
20891   config[4].type = VL_API_CLIENT_RING;
20892   config[4].size = 1024;
20893   config[4].count = 16;
20894
20895   config[5].type = VL_API_CLIENT_RING;
20896   config[5].size = 4096;
20897   config[5].count = 2;
20898
20899   config[6].type = VL_API_QUEUE;
20900   config[6].count = 128;
20901   config[6].size = sizeof (uword);
20902
20903   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20904   if (!rv)
20905     vam->client_index_invalid = 1;
20906   return rv;
20907 #else
20908   return -99;
20909 #endif
20910 }
20911
20912 static int
20913 api_dns_enable_disable (vat_main_t * vam)
20914 {
20915   unformat_input_t *line_input = vam->input;
20916   vl_api_dns_enable_disable_t *mp;
20917   u8 enable_disable = 1;
20918   int ret;
20919
20920   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20921     {
20922       if (unformat (line_input, "disable"))
20923         enable_disable = 0;
20924       if (unformat (line_input, "enable"))
20925         enable_disable = 1;
20926       else
20927         break;
20928     }
20929
20930   /* Construct the API message */
20931   M (DNS_ENABLE_DISABLE, mp);
20932   mp->enable = enable_disable;
20933
20934   /* send it... */
20935   S (mp);
20936   /* Wait for the reply */
20937   W (ret);
20938   return ret;
20939 }
20940
20941 static int
20942 api_dns_resolve_name (vat_main_t * vam)
20943 {
20944   unformat_input_t *line_input = vam->input;
20945   vl_api_dns_resolve_name_t *mp;
20946   u8 *name = 0;
20947   int ret;
20948
20949   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20950     {
20951       if (unformat (line_input, "%s", &name))
20952         ;
20953       else
20954         break;
20955     }
20956
20957   if (vec_len (name) > 127)
20958     {
20959       errmsg ("name too long");
20960       return -99;
20961     }
20962
20963   /* Construct the API message */
20964   M (DNS_RESOLVE_NAME, mp);
20965   memcpy (mp->name, name, vec_len (name));
20966   vec_free (name);
20967
20968   /* send it... */
20969   S (mp);
20970   /* Wait for the reply */
20971   W (ret);
20972   return ret;
20973 }
20974
20975 static int
20976 api_dns_resolve_ip (vat_main_t * vam)
20977 {
20978   unformat_input_t *line_input = vam->input;
20979   vl_api_dns_resolve_ip_t *mp;
20980   int is_ip6 = -1;
20981   ip4_address_t addr4;
20982   ip6_address_t addr6;
20983   int ret;
20984
20985   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20986     {
20987       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
20988         is_ip6 = 1;
20989       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
20990         is_ip6 = 0;
20991       else
20992         break;
20993     }
20994
20995   if (is_ip6 == -1)
20996     {
20997       errmsg ("missing address");
20998       return -99;
20999     }
21000
21001   /* Construct the API message */
21002   M (DNS_RESOLVE_IP, mp);
21003   mp->is_ip6 = is_ip6;
21004   if (is_ip6)
21005     memcpy (mp->address, &addr6, sizeof (addr6));
21006   else
21007     memcpy (mp->address, &addr4, sizeof (addr4));
21008
21009   /* send it... */
21010   S (mp);
21011   /* Wait for the reply */
21012   W (ret);
21013   return ret;
21014 }
21015
21016 static int
21017 api_dns_name_server_add_del (vat_main_t * vam)
21018 {
21019   unformat_input_t *i = vam->input;
21020   vl_api_dns_name_server_add_del_t *mp;
21021   u8 is_add = 1;
21022   ip6_address_t ip6_server;
21023   ip4_address_t ip4_server;
21024   int ip6_set = 0;
21025   int ip4_set = 0;
21026   int ret = 0;
21027
21028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21029     {
21030       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21031         ip6_set = 1;
21032       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21033         ip4_set = 1;
21034       else if (unformat (i, "del"))
21035         is_add = 0;
21036       else
21037         {
21038           clib_warning ("parse error '%U'", format_unformat_error, i);
21039           return -99;
21040         }
21041     }
21042
21043   if (ip4_set && ip6_set)
21044     {
21045       errmsg ("Only one server address allowed per message");
21046       return -99;
21047     }
21048   if ((ip4_set + ip6_set) == 0)
21049     {
21050       errmsg ("Server address required");
21051       return -99;
21052     }
21053
21054   /* Construct the API message */
21055   M (DNS_NAME_SERVER_ADD_DEL, mp);
21056
21057   if (ip6_set)
21058     {
21059       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21060       mp->is_ip6 = 1;
21061     }
21062   else
21063     {
21064       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21065       mp->is_ip6 = 0;
21066     }
21067
21068   mp->is_add = is_add;
21069
21070   /* send it... */
21071   S (mp);
21072
21073   /* Wait for a reply, return good/bad news  */
21074   W (ret);
21075   return ret;
21076 }
21077
21078 static void
21079 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21080 {
21081   vat_main_t *vam = &vat_main;
21082
21083   if (mp->is_ip4)
21084     {
21085       print (vam->ofp,
21086              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21087              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21088              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21089              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21090              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21091              clib_net_to_host_u32 (mp->action_index), mp->tag);
21092     }
21093   else
21094     {
21095       print (vam->ofp,
21096              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21097              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21098              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21099              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21100              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21101              clib_net_to_host_u32 (mp->action_index), mp->tag);
21102     }
21103 }
21104
21105 static void
21106 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21107                                              mp)
21108 {
21109   vat_main_t *vam = &vat_main;
21110   vat_json_node_t *node = NULL;
21111   struct in6_addr ip6;
21112   struct in_addr ip4;
21113
21114   if (VAT_JSON_ARRAY != vam->json_tree.type)
21115     {
21116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21117       vat_json_init_array (&vam->json_tree);
21118     }
21119   node = vat_json_array_add (&vam->json_tree);
21120   vat_json_init_object (node);
21121
21122   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21123   vat_json_object_add_uint (node, "appns_index",
21124                             clib_net_to_host_u32 (mp->appns_index));
21125   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21126   vat_json_object_add_uint (node, "scope", mp->scope);
21127   vat_json_object_add_uint (node, "action_index",
21128                             clib_net_to_host_u32 (mp->action_index));
21129   vat_json_object_add_uint (node, "lcl_port",
21130                             clib_net_to_host_u16 (mp->lcl_port));
21131   vat_json_object_add_uint (node, "rmt_port",
21132                             clib_net_to_host_u16 (mp->rmt_port));
21133   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21134   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21135   vat_json_object_add_string_copy (node, "tag", mp->tag);
21136   if (mp->is_ip4)
21137     {
21138       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21139       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21140       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21141       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21142     }
21143   else
21144     {
21145       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21146       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21147       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21148       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21149     }
21150 }
21151
21152 static int
21153 api_session_rule_add_del (vat_main_t * vam)
21154 {
21155   vl_api_session_rule_add_del_t *mp;
21156   unformat_input_t *i = vam->input;
21157   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21158   u32 appns_index = 0, scope = 0;
21159   ip4_address_t lcl_ip4, rmt_ip4;
21160   ip6_address_t lcl_ip6, rmt_ip6;
21161   u8 is_ip4 = 1, conn_set = 0;
21162   u8 is_add = 1, *tag = 0;
21163   int ret;
21164
21165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21166     {
21167       if (unformat (i, "del"))
21168         is_add = 0;
21169       else if (unformat (i, "add"))
21170         ;
21171       else if (unformat (i, "proto tcp"))
21172         proto = 0;
21173       else if (unformat (i, "proto udp"))
21174         proto = 1;
21175       else if (unformat (i, "appns %d", &appns_index))
21176         ;
21177       else if (unformat (i, "scope %d", &scope))
21178         ;
21179       else if (unformat (i, "tag %_%v%_", &tag))
21180         ;
21181       else
21182         if (unformat
21183             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21184              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21185              &rmt_port))
21186         {
21187           is_ip4 = 1;
21188           conn_set = 1;
21189         }
21190       else
21191         if (unformat
21192             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21193              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21194              &rmt_port))
21195         {
21196           is_ip4 = 0;
21197           conn_set = 1;
21198         }
21199       else if (unformat (i, "action %d", &action))
21200         ;
21201       else
21202         break;
21203     }
21204   if (proto == ~0 || !conn_set || action == ~0)
21205     {
21206       errmsg ("transport proto, connection and action must be set");
21207       return -99;
21208     }
21209
21210   if (scope > 3)
21211     {
21212       errmsg ("scope should be 0-3");
21213       return -99;
21214     }
21215
21216   M (SESSION_RULE_ADD_DEL, mp);
21217
21218   mp->is_ip4 = is_ip4;
21219   mp->transport_proto = proto;
21220   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21221   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21222   mp->lcl_plen = lcl_plen;
21223   mp->rmt_plen = rmt_plen;
21224   mp->action_index = clib_host_to_net_u32 (action);
21225   mp->appns_index = clib_host_to_net_u32 (appns_index);
21226   mp->scope = scope;
21227   mp->is_add = is_add;
21228   if (is_ip4)
21229     {
21230       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21231       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21232     }
21233   else
21234     {
21235       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21236       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21237     }
21238   if (tag)
21239     {
21240       clib_memcpy (mp->tag, tag, vec_len (tag));
21241       vec_free (tag);
21242     }
21243
21244   S (mp);
21245   W (ret);
21246   return ret;
21247 }
21248
21249 static int
21250 api_session_rules_dump (vat_main_t * vam)
21251 {
21252   vl_api_session_rules_dump_t *mp;
21253   vl_api_control_ping_t *mp_ping;
21254   int ret;
21255
21256   if (!vam->json_output)
21257     {
21258       print (vam->ofp, "%=20s", "Session Rules");
21259     }
21260
21261   M (SESSION_RULES_DUMP, mp);
21262   /* send it... */
21263   S (mp);
21264
21265   /* Use a control ping for synchronization */
21266   MPING (CONTROL_PING, mp_ping);
21267   S (mp_ping);
21268
21269   /* Wait for a reply... */
21270   W (ret);
21271   return ret;
21272 }
21273
21274 static int
21275 api_ip_container_proxy_add_del (vat_main_t * vam)
21276 {
21277   vl_api_ip_container_proxy_add_del_t *mp;
21278   unformat_input_t *i = vam->input;
21279   u32 sw_if_index = ~0;
21280   vl_api_prefix_t pfx = { };
21281   u8 is_add = 1;
21282   int ret;
21283
21284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21285     {
21286       if (unformat (i, "del"))
21287         is_add = 0;
21288       else if (unformat (i, "add"))
21289         ;
21290       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21291         ;
21292       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21293         ;
21294       else
21295         break;
21296     }
21297   if (sw_if_index == ~0 || pfx.address_length == 0)
21298     {
21299       errmsg ("address and sw_if_index must be set");
21300       return -99;
21301     }
21302
21303   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21304
21305   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21306   mp->is_add = is_add;
21307   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21308
21309   S (mp);
21310   W (ret);
21311   return ret;
21312 }
21313
21314 static int
21315 api_qos_record_enable_disable (vat_main_t * vam)
21316 {
21317   unformat_input_t *i = vam->input;
21318   vl_api_qos_record_enable_disable_t *mp;
21319   u32 sw_if_index, qs = 0xff;
21320   u8 sw_if_index_set = 0;
21321   u8 enable = 1;
21322   int ret;
21323
21324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21325     {
21326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21327         sw_if_index_set = 1;
21328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21329         sw_if_index_set = 1;
21330       else if (unformat (i, "%U", unformat_qos_source, &qs))
21331         ;
21332       else if (unformat (i, "disable"))
21333         enable = 0;
21334       else
21335         {
21336           clib_warning ("parse error '%U'", format_unformat_error, i);
21337           return -99;
21338         }
21339     }
21340
21341   if (sw_if_index_set == 0)
21342     {
21343       errmsg ("missing interface name or sw_if_index");
21344       return -99;
21345     }
21346   if (qs == 0xff)
21347     {
21348       errmsg ("input location must be specified");
21349       return -99;
21350     }
21351
21352   M (QOS_RECORD_ENABLE_DISABLE, mp);
21353
21354   mp->sw_if_index = ntohl (sw_if_index);
21355   mp->input_source = qs;
21356   mp->enable = enable;
21357
21358   S (mp);
21359   W (ret);
21360   return ret;
21361 }
21362
21363
21364 static int
21365 q_or_quit (vat_main_t * vam)
21366 {
21367 #if VPP_API_TEST_BUILTIN == 0
21368   longjmp (vam->jump_buf, 1);
21369 #endif
21370   return 0;                     /* not so much */
21371 }
21372
21373 static int
21374 q (vat_main_t * vam)
21375 {
21376   return q_or_quit (vam);
21377 }
21378
21379 static int
21380 quit (vat_main_t * vam)
21381 {
21382   return q_or_quit (vam);
21383 }
21384
21385 static int
21386 comment (vat_main_t * vam)
21387 {
21388   return 0;
21389 }
21390
21391 static int
21392 statseg (vat_main_t * vam)
21393 {
21394   ssvm_private_t *ssvmp = &vam->stat_segment;
21395   ssvm_shared_header_t *shared_header = ssvmp->sh;
21396   vlib_counter_t **counters;
21397   u64 thread0_index1_packets;
21398   u64 thread0_index1_bytes;
21399   f64 vector_rate, input_rate;
21400   uword *p;
21401
21402   uword *counter_vector_by_name;
21403   if (vam->stat_segment_lockp == 0)
21404     {
21405       errmsg ("Stat segment not mapped...");
21406       return -99;
21407     }
21408
21409   /* look up "/if/rx for sw_if_index 1 as a test */
21410
21411   clib_spinlock_lock (vam->stat_segment_lockp);
21412
21413   counter_vector_by_name = (uword *) shared_header->opaque[1];
21414
21415   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21416   if (p == 0)
21417     {
21418       clib_spinlock_unlock (vam->stat_segment_lockp);
21419       errmsg ("/if/tx not found?");
21420       return -99;
21421     }
21422
21423   /* Fish per-thread vector of combined counters from shared memory */
21424   counters = (vlib_counter_t **) p[0];
21425
21426   if (vec_len (counters[0]) < 2)
21427     {
21428       clib_spinlock_unlock (vam->stat_segment_lockp);
21429       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21430       return -99;
21431     }
21432
21433   /* Read thread 0 sw_if_index 1 counter */
21434   thread0_index1_packets = counters[0][1].packets;
21435   thread0_index1_bytes = counters[0][1].bytes;
21436
21437   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21438   if (p == 0)
21439     {
21440       clib_spinlock_unlock (vam->stat_segment_lockp);
21441       errmsg ("vector_rate not found?");
21442       return -99;
21443     }
21444
21445   vector_rate = *(f64 *) (p[0]);
21446   p = hash_get_mem (counter_vector_by_name, "input_rate");
21447   if (p == 0)
21448     {
21449       clib_spinlock_unlock (vam->stat_segment_lockp);
21450       errmsg ("input_rate not found?");
21451       return -99;
21452     }
21453   input_rate = *(f64 *) (p[0]);
21454
21455   clib_spinlock_unlock (vam->stat_segment_lockp);
21456
21457   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21458          vector_rate, input_rate);
21459   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21460          thread0_index1_packets, thread0_index1_bytes);
21461
21462   return 0;
21463 }
21464
21465 static int
21466 cmd_cmp (void *a1, void *a2)
21467 {
21468   u8 **c1 = a1;
21469   u8 **c2 = a2;
21470
21471   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21472 }
21473
21474 static int
21475 help (vat_main_t * vam)
21476 {
21477   u8 **cmds = 0;
21478   u8 *name = 0;
21479   hash_pair_t *p;
21480   unformat_input_t *i = vam->input;
21481   int j;
21482
21483   if (unformat (i, "%s", &name))
21484     {
21485       uword *hs;
21486
21487       vec_add1 (name, 0);
21488
21489       hs = hash_get_mem (vam->help_by_name, name);
21490       if (hs)
21491         print (vam->ofp, "usage: %s %s", name, hs[0]);
21492       else
21493         print (vam->ofp, "No such msg / command '%s'", name);
21494       vec_free (name);
21495       return 0;
21496     }
21497
21498   print (vam->ofp, "Help is available for the following:");
21499
21500     /* *INDENT-OFF* */
21501     hash_foreach_pair (p, vam->function_by_name,
21502     ({
21503       vec_add1 (cmds, (u8 *)(p->key));
21504     }));
21505     /* *INDENT-ON* */
21506
21507   vec_sort_with_function (cmds, cmd_cmp);
21508
21509   for (j = 0; j < vec_len (cmds); j++)
21510     print (vam->ofp, "%s", cmds[j]);
21511
21512   vec_free (cmds);
21513   return 0;
21514 }
21515
21516 static int
21517 set (vat_main_t * vam)
21518 {
21519   u8 *name = 0, *value = 0;
21520   unformat_input_t *i = vam->input;
21521
21522   if (unformat (i, "%s", &name))
21523     {
21524       /* The input buffer is a vector, not a string. */
21525       value = vec_dup (i->buffer);
21526       vec_delete (value, i->index, 0);
21527       /* Almost certainly has a trailing newline */
21528       if (value[vec_len (value) - 1] == '\n')
21529         value[vec_len (value) - 1] = 0;
21530       /* Make sure it's a proper string, one way or the other */
21531       vec_add1 (value, 0);
21532       (void) clib_macro_set_value (&vam->macro_main,
21533                                    (char *) name, (char *) value);
21534     }
21535   else
21536     errmsg ("usage: set <name> <value>");
21537
21538   vec_free (name);
21539   vec_free (value);
21540   return 0;
21541 }
21542
21543 static int
21544 unset (vat_main_t * vam)
21545 {
21546   u8 *name = 0;
21547
21548   if (unformat (vam->input, "%s", &name))
21549     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21550       errmsg ("unset: %s wasn't set", name);
21551   vec_free (name);
21552   return 0;
21553 }
21554
21555 typedef struct
21556 {
21557   u8 *name;
21558   u8 *value;
21559 } macro_sort_t;
21560
21561
21562 static int
21563 macro_sort_cmp (void *a1, void *a2)
21564 {
21565   macro_sort_t *s1 = a1;
21566   macro_sort_t *s2 = a2;
21567
21568   return strcmp ((char *) (s1->name), (char *) (s2->name));
21569 }
21570
21571 static int
21572 dump_macro_table (vat_main_t * vam)
21573 {
21574   macro_sort_t *sort_me = 0, *sm;
21575   int i;
21576   hash_pair_t *p;
21577
21578     /* *INDENT-OFF* */
21579     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21580     ({
21581       vec_add2 (sort_me, sm, 1);
21582       sm->name = (u8 *)(p->key);
21583       sm->value = (u8 *) (p->value[0]);
21584     }));
21585     /* *INDENT-ON* */
21586
21587   vec_sort_with_function (sort_me, macro_sort_cmp);
21588
21589   if (vec_len (sort_me))
21590     print (vam->ofp, "%-15s%s", "Name", "Value");
21591   else
21592     print (vam->ofp, "The macro table is empty...");
21593
21594   for (i = 0; i < vec_len (sort_me); i++)
21595     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21596   return 0;
21597 }
21598
21599 static int
21600 dump_node_table (vat_main_t * vam)
21601 {
21602   int i, j;
21603   vlib_node_t *node, *next_node;
21604
21605   if (vec_len (vam->graph_nodes) == 0)
21606     {
21607       print (vam->ofp, "Node table empty, issue get_node_graph...");
21608       return 0;
21609     }
21610
21611   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21612     {
21613       node = vam->graph_nodes[0][i];
21614       print (vam->ofp, "[%d] %s", i, node->name);
21615       for (j = 0; j < vec_len (node->next_nodes); j++)
21616         {
21617           if (node->next_nodes[j] != ~0)
21618             {
21619               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21620               print (vam->ofp, "  [%d] %s", j, next_node->name);
21621             }
21622         }
21623     }
21624   return 0;
21625 }
21626
21627 static int
21628 value_sort_cmp (void *a1, void *a2)
21629 {
21630   name_sort_t *n1 = a1;
21631   name_sort_t *n2 = a2;
21632
21633   if (n1->value < n2->value)
21634     return -1;
21635   if (n1->value > n2->value)
21636     return 1;
21637   return 0;
21638 }
21639
21640
21641 static int
21642 dump_msg_api_table (vat_main_t * vam)
21643 {
21644   api_main_t *am = &api_main;
21645   name_sort_t *nses = 0, *ns;
21646   hash_pair_t *hp;
21647   int i;
21648
21649   /* *INDENT-OFF* */
21650   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21651   ({
21652     vec_add2 (nses, ns, 1);
21653     ns->name = (u8 *)(hp->key);
21654     ns->value = (u32) hp->value[0];
21655   }));
21656   /* *INDENT-ON* */
21657
21658   vec_sort_with_function (nses, value_sort_cmp);
21659
21660   for (i = 0; i < vec_len (nses); i++)
21661     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21662   vec_free (nses);
21663   return 0;
21664 }
21665
21666 static int
21667 get_msg_id (vat_main_t * vam)
21668 {
21669   u8 *name_and_crc;
21670   u32 message_index;
21671
21672   if (unformat (vam->input, "%s", &name_and_crc))
21673     {
21674       message_index = vl_msg_api_get_msg_index (name_and_crc);
21675       if (message_index == ~0)
21676         {
21677           print (vam->ofp, " '%s' not found", name_and_crc);
21678           return 0;
21679         }
21680       print (vam->ofp, " '%s' has message index %d",
21681              name_and_crc, message_index);
21682       return 0;
21683     }
21684   errmsg ("name_and_crc required...");
21685   return 0;
21686 }
21687
21688 static int
21689 search_node_table (vat_main_t * vam)
21690 {
21691   unformat_input_t *line_input = vam->input;
21692   u8 *node_to_find;
21693   int j;
21694   vlib_node_t *node, *next_node;
21695   uword *p;
21696
21697   if (vam->graph_node_index_by_name == 0)
21698     {
21699       print (vam->ofp, "Node table empty, issue get_node_graph...");
21700       return 0;
21701     }
21702
21703   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21704     {
21705       if (unformat (line_input, "%s", &node_to_find))
21706         {
21707           vec_add1 (node_to_find, 0);
21708           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21709           if (p == 0)
21710             {
21711               print (vam->ofp, "%s not found...", node_to_find);
21712               goto out;
21713             }
21714           node = vam->graph_nodes[0][p[0]];
21715           print (vam->ofp, "[%d] %s", p[0], node->name);
21716           for (j = 0; j < vec_len (node->next_nodes); j++)
21717             {
21718               if (node->next_nodes[j] != ~0)
21719                 {
21720                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21721                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21722                 }
21723             }
21724         }
21725
21726       else
21727         {
21728           clib_warning ("parse error '%U'", format_unformat_error,
21729                         line_input);
21730           return -99;
21731         }
21732
21733     out:
21734       vec_free (node_to_find);
21735
21736     }
21737
21738   return 0;
21739 }
21740
21741
21742 static int
21743 script (vat_main_t * vam)
21744 {
21745 #if (VPP_API_TEST_BUILTIN==0)
21746   u8 *s = 0;
21747   char *save_current_file;
21748   unformat_input_t save_input;
21749   jmp_buf save_jump_buf;
21750   u32 save_line_number;
21751
21752   FILE *new_fp, *save_ifp;
21753
21754   if (unformat (vam->input, "%s", &s))
21755     {
21756       new_fp = fopen ((char *) s, "r");
21757       if (new_fp == 0)
21758         {
21759           errmsg ("Couldn't open script file %s", s);
21760           vec_free (s);
21761           return -99;
21762         }
21763     }
21764   else
21765     {
21766       errmsg ("Missing script name");
21767       return -99;
21768     }
21769
21770   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21771   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21772   save_ifp = vam->ifp;
21773   save_line_number = vam->input_line_number;
21774   save_current_file = (char *) vam->current_file;
21775
21776   vam->input_line_number = 0;
21777   vam->ifp = new_fp;
21778   vam->current_file = s;
21779   do_one_file (vam);
21780
21781   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21782   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21783   vam->ifp = save_ifp;
21784   vam->input_line_number = save_line_number;
21785   vam->current_file = (u8 *) save_current_file;
21786   vec_free (s);
21787
21788   return 0;
21789 #else
21790   clib_warning ("use the exec command...");
21791   return -99;
21792 #endif
21793 }
21794
21795 static int
21796 echo (vat_main_t * vam)
21797 {
21798   print (vam->ofp, "%v", vam->input->buffer);
21799   return 0;
21800 }
21801
21802 /* List of API message constructors, CLI names map to api_xxx */
21803 #define foreach_vpe_api_msg                                             \
21804 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21805 _(sw_interface_dump,"")                                                 \
21806 _(sw_interface_set_flags,                                               \
21807   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21808 _(sw_interface_add_del_address,                                         \
21809   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21810 _(sw_interface_set_rx_mode,                                             \
21811   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21812 _(sw_interface_set_rx_placement,                                        \
21813   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21814 _(sw_interface_rx_placement_dump,                                       \
21815   "[<intfc> | sw_if_index <id>]")                                         \
21816 _(sw_interface_set_table,                                               \
21817   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21818 _(sw_interface_set_mpls_enable,                                         \
21819   "<intfc> | sw_if_index [disable | dis]")                              \
21820 _(sw_interface_set_vpath,                                               \
21821   "<intfc> | sw_if_index <id> enable | disable")                        \
21822 _(sw_interface_set_vxlan_bypass,                                        \
21823   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21824 _(sw_interface_set_geneve_bypass,                                       \
21825   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21826 _(sw_interface_set_l2_xconnect,                                         \
21827   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21828   "enable | disable")                                                   \
21829 _(sw_interface_set_l2_bridge,                                           \
21830   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21831   "[shg <split-horizon-group>] [bvi]\n"                                 \
21832   "enable | disable")                                                   \
21833 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21834 _(bridge_domain_add_del,                                                \
21835   "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") \
21836 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21837 _(l2fib_add_del,                                                        \
21838   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21839 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21840 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21841 _(l2_flags,                                                             \
21842   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21843 _(bridge_flags,                                                         \
21844   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21845 _(tap_create_v2,                                                        \
21846   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
21847 _(tap_delete_v2,                                                        \
21848   "<vpp-if-name> | sw_if_index <id>")                                   \
21849 _(sw_interface_tap_v2_dump, "")                                         \
21850 _(virtio_pci_create,                                                    \
21851   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21852 _(virtio_pci_delete,                                                    \
21853   "<vpp-if-name> | sw_if_index <id>")                                   \
21854 _(sw_interface_virtio_pci_dump, "")                                     \
21855 _(bond_create,                                                          \
21856   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21857   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21858   "[id <if-id>]")                                                       \
21859 _(bond_delete,                                                          \
21860   "<vpp-if-name> | sw_if_index <id>")                                   \
21861 _(bond_enslave,                                                         \
21862   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21863 _(bond_detach_slave,                                                    \
21864   "sw_if_index <n>")                                                    \
21865 _(sw_interface_bond_dump, "")                                           \
21866 _(sw_interface_slave_dump,                                              \
21867   "<vpp-if-name> | sw_if_index <id>")                                   \
21868 _(ip_table_add_del,                                                     \
21869   "table <n> [ipv6] [add | del]\n")                                     \
21870 _(ip_route_add_del,                                                     \
21871   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21872   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21873   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21874   "[multipath] [count <n>] [del]")                                      \
21875 _(ip_mroute_add_del,                                                    \
21876   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21877   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21878 _(mpls_table_add_del,                                                   \
21879   "table <n> [add | del]\n")                                            \
21880 _(mpls_route_add_del,                                                   \
21881   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21882   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21883   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21884   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21885   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21886   "[count <n>] [del]")                                                  \
21887 _(mpls_ip_bind_unbind,                                                  \
21888   "<label> <addr/len>")                                                 \
21889 _(mpls_tunnel_add_del,                                                  \
21890   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21891   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21892   "[l2-only]  [out-label <n>]")                                         \
21893 _(sr_mpls_policy_add,                                                   \
21894   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21895 _(sr_mpls_policy_del,                                                   \
21896   "bsid <id>")                                                          \
21897 _(bier_table_add_del,                                                   \
21898   "<label> <sub-domain> <set> <bsl> [del]")                             \
21899 _(bier_route_add_del,                                                   \
21900   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21901   "[<intfc> | sw_if_index <id>]"                                        \
21902   "[weight <n>] [del] [multipath]")                                     \
21903 _(proxy_arp_add_del,                                                    \
21904   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21905 _(proxy_arp_intfc_enable_disable,                                       \
21906   "<intfc> | sw_if_index <id> enable | disable")                        \
21907 _(sw_interface_set_unnumbered,                                          \
21908   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21909 _(ip_neighbor_add_del,                                                  \
21910   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21911   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21912 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21913 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21914   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21915   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21916   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21917 _(reset_fib, "vrf <n> [ipv6]")                                          \
21918 _(dhcp_proxy_config,                                                    \
21919   "svr <v46-address> src <v46-address>\n"                               \
21920    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21921 _(dhcp_proxy_set_vss,                                                   \
21922   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21923 _(dhcp_proxy_dump, "ip6")                                               \
21924 _(dhcp_client_config,                                                   \
21925   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21926 _(set_ip_flow_hash,                                                     \
21927   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21928 _(sw_interface_ip6_enable_disable,                                      \
21929   "<intfc> | sw_if_index <id> enable | disable")                        \
21930 _(ip6nd_proxy_add_del,                                                  \
21931   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21932 _(ip6nd_proxy_dump, "")                                                 \
21933 _(sw_interface_ip6nd_ra_prefix,                                         \
21934   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21935   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21936   "[nolink] [isno]")                                                    \
21937 _(sw_interface_ip6nd_ra_config,                                         \
21938   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21939   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21940   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21941 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21942 _(l2_patch_add_del,                                                     \
21943   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21944   "enable | disable")                                                   \
21945 _(sr_localsid_add_del,                                                  \
21946   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21947   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21948 _(classify_add_del_table,                                               \
21949   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21950   " [del] [del-chain] mask <mask-value>\n"                              \
21951   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21952   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21953 _(classify_add_del_session,                                             \
21954   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21955   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21956   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21957   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21958 _(classify_set_interface_ip_table,                                      \
21959   "<intfc> | sw_if_index <nn> table <nn>")                              \
21960 _(classify_set_interface_l2_tables,                                     \
21961   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21962   "  [other-table <nn>]")                                               \
21963 _(get_node_index, "node <node-name")                                    \
21964 _(add_node_next, "node <node-name> next <next-node-name>")              \
21965 _(l2tpv3_create_tunnel,                                                 \
21966   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21967   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21968   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21969 _(l2tpv3_set_tunnel_cookies,                                            \
21970   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21971   "[new_remote_cookie <nn>]\n")                                         \
21972 _(l2tpv3_interface_enable_disable,                                      \
21973   "<intfc> | sw_if_index <nn> enable | disable")                        \
21974 _(l2tpv3_set_lookup_key,                                                \
21975   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21976 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21977 _(vxlan_offload_rx,                                                     \
21978   "hw { <interface name> | hw_if_index <nn>} "                          \
21979   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21980 _(vxlan_add_del_tunnel,                                                 \
21981   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21982   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21983   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21984 _(geneve_add_del_tunnel,                                                \
21985   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21986   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21987   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21988 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21989 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21990 _(gre_tunnel_add_del,                                                   \
21991   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21992   "[teb | erspan <session-id>] [del]")                                  \
21993 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21994 _(l2_fib_clear_table, "")                                               \
21995 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21996 _(l2_interface_vlan_tag_rewrite,                                        \
21997   "<intfc> | sw_if_index <nn> \n"                                       \
21998   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21999   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22000 _(create_vhost_user_if,                                                 \
22001         "socket <filename> [server] [renumber <dev_instance>] "         \
22002         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22003         "[mac <mac_address>]")                                          \
22004 _(modify_vhost_user_if,                                                 \
22005         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22006         "[server] [renumber <dev_instance>]")                           \
22007 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22008 _(sw_interface_vhost_user_dump, "")                                     \
22009 _(show_version, "")                                                     \
22010 _(show_threads, "")                                                     \
22011 _(vxlan_gpe_add_del_tunnel,                                             \
22012   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22013   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22014   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22015   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22016 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22017 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22018 _(interface_name_renumber,                                              \
22019   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22020 _(input_acl_set_interface,                                              \
22021   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22022   "  [l2-table <nn>] [del]")                                            \
22023 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22024 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22025   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22026 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22027 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22028 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22029 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22030 _(ip_dump, "ipv4 | ipv6")                                               \
22031 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22032 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22033   "  spid_id <n> ")                                                     \
22034 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22035   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22036   "  integ_alg <alg> integ_key <hex>")                                  \
22037 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22038   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22039   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22040   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22041 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22042   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22043   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22044   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22045   "  [instance <n>]")     \
22046 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22047 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22048 _(delete_loopback,"sw_if_index <nn>")                                   \
22049 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22050 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22051 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22052 _(want_interface_events,  "enable|disable")                             \
22053 _(get_first_msg_id, "client <name>")                                    \
22054 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22055 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22056   "fib-id <nn> [ip4][ip6][default]")                                    \
22057 _(get_node_graph, " ")                                                  \
22058 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22059 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22060 _(ioam_disable, "")                                                     \
22061 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22062                             " sw_if_index <sw_if_index> p <priority> "  \
22063                             "w <weight>] [del]")                        \
22064 _(one_add_del_locator, "locator-set <locator_name> "                    \
22065                         "iface <intf> | sw_if_index <sw_if_index> "     \
22066                         "p <priority> w <weight> [del]")                \
22067 _(one_add_del_local_eid,"vni <vni> eid "                                \
22068                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22069                          "locator-set <locator_name> [del]"             \
22070                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22071 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22072 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22073 _(one_enable_disable, "enable|disable")                                 \
22074 _(one_map_register_enable_disable, "enable|disable")                    \
22075 _(one_map_register_fallback_threshold, "<value>")                       \
22076 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22077 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22078                                "[seid <seid>] "                         \
22079                                "rloc <locator> p <prio> "               \
22080                                "w <weight> [rloc <loc> ... ] "          \
22081                                "action <action> [del-all]")             \
22082 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22083                           "<local-eid>")                                \
22084 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22085 _(one_use_petr, "ip-address> | disable")                                \
22086 _(one_map_request_mode, "src-dst|dst-only")                             \
22087 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22088 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22089 _(one_locator_set_dump, "[local | remote]")                             \
22090 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22091 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22092                        "[local] | [remote]")                            \
22093 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22094 _(one_ndp_bd_get, "")                                                   \
22095 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22096 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22097 _(one_l2_arp_bd_get, "")                                                \
22098 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22099 _(one_stats_enable_disable, "enable|disable")                           \
22100 _(show_one_stats_enable_disable, "")                                    \
22101 _(one_eid_table_vni_dump, "")                                           \
22102 _(one_eid_table_map_dump, "l2|l3")                                      \
22103 _(one_map_resolver_dump, "")                                            \
22104 _(one_map_server_dump, "")                                              \
22105 _(one_adjacencies_get, "vni <vni>")                                     \
22106 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22107 _(show_one_rloc_probe_state, "")                                        \
22108 _(show_one_map_register_state, "")                                      \
22109 _(show_one_status, "")                                                  \
22110 _(one_stats_dump, "")                                                   \
22111 _(one_stats_flush, "")                                                  \
22112 _(one_get_map_request_itr_rlocs, "")                                    \
22113 _(one_map_register_set_ttl, "<ttl>")                                    \
22114 _(one_set_transport_protocol, "udp|api")                                \
22115 _(one_get_transport_protocol, "")                                       \
22116 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22117 _(one_show_xtr_mode, "")                                                \
22118 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22119 _(one_show_pitr_mode, "")                                               \
22120 _(one_enable_disable_petr_mode, "enable|disable")                       \
22121 _(one_show_petr_mode, "")                                               \
22122 _(show_one_nsh_mapping, "")                                             \
22123 _(show_one_pitr, "")                                                    \
22124 _(show_one_use_petr, "")                                                \
22125 _(show_one_map_request_mode, "")                                        \
22126 _(show_one_map_register_ttl, "")                                        \
22127 _(show_one_map_register_fallback_threshold, "")                         \
22128 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22129                             " sw_if_index <sw_if_index> p <priority> "  \
22130                             "w <weight>] [del]")                        \
22131 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22132                         "iface <intf> | sw_if_index <sw_if_index> "     \
22133                         "p <priority> w <weight> [del]")                \
22134 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22135                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22136                          "locator-set <locator_name> [del]"             \
22137                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22138 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22139 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22140 _(lisp_enable_disable, "enable|disable")                                \
22141 _(lisp_map_register_enable_disable, "enable|disable")                   \
22142 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22143 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22144                                "[seid <seid>] "                         \
22145                                "rloc <locator> p <prio> "               \
22146                                "w <weight> [rloc <loc> ... ] "          \
22147                                "action <action> [del-all]")             \
22148 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22149                           "<local-eid>")                                \
22150 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22151 _(lisp_use_petr, "<ip-address> | disable")                              \
22152 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22153 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22154 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22155 _(lisp_locator_set_dump, "[local | remote]")                            \
22156 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22157 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22158                        "[local] | [remote]")                            \
22159 _(lisp_eid_table_vni_dump, "")                                          \
22160 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22161 _(lisp_map_resolver_dump, "")                                           \
22162 _(lisp_map_server_dump, "")                                             \
22163 _(lisp_adjacencies_get, "vni <vni>")                                    \
22164 _(gpe_fwd_entry_vnis_get, "")                                           \
22165 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22166 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22167                                 "[table <table-id>]")                   \
22168 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22169 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22170 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22171 _(gpe_get_encap_mode, "")                                               \
22172 _(lisp_gpe_add_del_iface, "up|down")                                    \
22173 _(lisp_gpe_enable_disable, "enable|disable")                            \
22174 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22175   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22176 _(show_lisp_rloc_probe_state, "")                                       \
22177 _(show_lisp_map_register_state, "")                                     \
22178 _(show_lisp_status, "")                                                 \
22179 _(lisp_get_map_request_itr_rlocs, "")                                   \
22180 _(show_lisp_pitr, "")                                                   \
22181 _(show_lisp_use_petr, "")                                               \
22182 _(show_lisp_map_request_mode, "")                                       \
22183 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22184 _(af_packet_delete, "name <host interface name>")                       \
22185 _(af_packet_dump, "")                                                   \
22186 _(policer_add_del, "name <policer name> <params> [del]")                \
22187 _(policer_dump, "[name <policer name>]")                                \
22188 _(policer_classify_set_interface,                                       \
22189   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22190   "  [l2-table <nn>] [del]")                                            \
22191 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22192 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22193     "[master|slave]")                                                   \
22194 _(netmap_delete, "name <interface name>")                               \
22195 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22196 _(mpls_table_dump, "")                                                  \
22197 _(mpls_route_dump, "table-id <ID>")                                     \
22198 _(classify_table_ids, "")                                               \
22199 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22200 _(classify_table_info, "table_id <nn>")                                 \
22201 _(classify_session_dump, "table_id <nn>")                               \
22202 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22203     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22204     "[template_interval <nn>] [udp_checksum]")                          \
22205 _(ipfix_exporter_dump, "")                                              \
22206 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22207 _(ipfix_classify_stream_dump, "")                                       \
22208 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22209 _(ipfix_classify_table_dump, "")                                        \
22210 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22211 _(sw_interface_span_dump, "[l2]")                                           \
22212 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22213 _(pg_create_interface, "if_id <nn>")                                    \
22214 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22215 _(pg_enable_disable, "[stream <id>] disable")                           \
22216 _(ip_source_and_port_range_check_add_del,                               \
22217   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22218 _(ip_source_and_port_range_check_interface_add_del,                     \
22219   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22220   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22221 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22222 _(l2_interface_pbb_tag_rewrite,                                         \
22223   "<intfc> | sw_if_index <nn> \n"                                       \
22224   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22225   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22226 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22227 _(flow_classify_set_interface,                                          \
22228   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22229 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22230 _(ip_table_dump, "")                                                    \
22231 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22232 _(ip_mtable_dump, "")                                                   \
22233 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22234 _(feature_enable_disable, "arc_name <arc_name> "                        \
22235   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22236 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22237 "[disable]")                                                            \
22238 _(l2_xconnect_dump, "")                                                 \
22239 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22240 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22241 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22242 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22243 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22244 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22245 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22246   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22247 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22248 _(sock_init_shm, "size <nnn>")                                          \
22249 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22250 _(dns_enable_disable, "[enable][disable]")                              \
22251 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22252 _(dns_resolve_name, "<hostname>")                                       \
22253 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22254 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22255 _(dns_resolve_name, "<hostname>")                                       \
22256 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22257   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22258 _(session_rules_dump, "")                                               \
22259 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22260 _(output_acl_set_interface,                                             \
22261   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22262   "  [l2-table <nn>] [del]")                                            \
22263 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22264
22265 /* List of command functions, CLI names map directly to functions */
22266 #define foreach_cli_function                                    \
22267 _(comment, "usage: comment <ignore-rest-of-line>")              \
22268 _(dump_interface_table, "usage: dump_interface_table")          \
22269 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22270 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22271 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22272 _(dump_macro_table, "usage: dump_macro_table ")                 \
22273 _(dump_node_table, "usage: dump_node_table")                    \
22274 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22275 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22276 _(echo, "usage: echo <message>")                                \
22277 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22278 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22279 _(help, "usage: help")                                          \
22280 _(q, "usage: quit")                                             \
22281 _(quit, "usage: quit")                                          \
22282 _(search_node_table, "usage: search_node_table <name>...")      \
22283 _(set, "usage: set <variable-name> <value>")                    \
22284 _(script, "usage: script <file-name>")                          \
22285 _(statseg, "usage: statseg")                                    \
22286 _(unset, "usage: unset <variable-name>")
22287
22288 #define _(N,n)                                  \
22289     static void vl_api_##n##_t_handler_uni      \
22290     (vl_api_##n##_t * mp)                       \
22291     {                                           \
22292         vat_main_t * vam = &vat_main;           \
22293         if (vam->json_output) {                 \
22294             vl_api_##n##_t_handler_json(mp);    \
22295         } else {                                \
22296             vl_api_##n##_t_handler(mp);         \
22297         }                                       \
22298     }
22299 foreach_vpe_api_reply_msg;
22300 #if VPP_API_TEST_BUILTIN == 0
22301 foreach_standalone_reply_msg;
22302 #endif
22303 #undef _
22304
22305 void
22306 vat_api_hookup (vat_main_t * vam)
22307 {
22308 #define _(N,n)                                                  \
22309     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22310                            vl_api_##n##_t_handler_uni,          \
22311                            vl_noop_handler,                     \
22312                            vl_api_##n##_t_endian,               \
22313                            vl_api_##n##_t_print,                \
22314                            sizeof(vl_api_##n##_t), 1);
22315   foreach_vpe_api_reply_msg;
22316 #if VPP_API_TEST_BUILTIN == 0
22317   foreach_standalone_reply_msg;
22318 #endif
22319 #undef _
22320
22321 #if (VPP_API_TEST_BUILTIN==0)
22322   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22323
22324   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22325
22326   vam->function_by_name = hash_create_string (0, sizeof (uword));
22327
22328   vam->help_by_name = hash_create_string (0, sizeof (uword));
22329 #endif
22330
22331   /* API messages we can send */
22332 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22333   foreach_vpe_api_msg;
22334 #undef _
22335
22336   /* Help strings */
22337 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22338   foreach_vpe_api_msg;
22339 #undef _
22340
22341   /* CLI functions */
22342 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22343   foreach_cli_function;
22344 #undef _
22345
22346   /* Help strings */
22347 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22348   foreach_cli_function;
22349 #undef _
22350 }
22351
22352 #if VPP_API_TEST_BUILTIN
22353 static clib_error_t *
22354 vat_api_hookup_shim (vlib_main_t * vm)
22355 {
22356   vat_api_hookup (&vat_main);
22357   return 0;
22358 }
22359
22360 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22361 #endif
22362
22363 /*
22364  * fd.io coding-style-patch-verification: ON
22365  *
22366  * Local Variables:
22367  * eval: (c-set-style "gnu")
22368  * End:
22369  */